File Index
Files and directories
Sign in
FILE

rcar_fdp1.c

File preview with syntax highlighting.

linux-6.19.14/drivers/media/platform/renesas/rcar_fdp1.c C
   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/platform_device.h>
  22#include <linux/pm_runtime.h>
  23#include <linux/sched.h>
  24#include <linux/slab.h>
  25#include <linux/timer.h>
  26#include <media/rcar-fcp.h>
  27#include <media/v4l2-ctrls.h>
  28#include <media/v4l2-device.h>
  29#include <media/v4l2-event.h>
  30#include <media/v4l2-ioctl.h>
  31#include <media/v4l2-mem2mem.h>
  32#include <media/videobuf2-dma-contig.h>
  33
  34static unsigned int debug;
  35module_param(debug, uint, 0644);
  36MODULE_PARM_DESC(debug, "activate debug info");
  37
  38/* Minimum and maximum frame width/height */
  39#define FDP1_MIN_W		80U
  40#define FDP1_MIN_H		80U
  41
  42#define FDP1_MAX_W		3840U
  43#define FDP1_MAX_H		2160U
  44
  45#define FDP1_MAX_PLANES		3U
  46#define FDP1_MAX_STRIDE		8190U
  47
  48/* Flags that indicate a format can be used for capture/output */
  49#define FDP1_CAPTURE		BIT(0)
  50#define FDP1_OUTPUT		BIT(1)
  51
  52#define DRIVER_NAME		"rcar_fdp1"
  53
  54/* Number of Job's to have available on the processing queue */
  55#define FDP1_NUMBER_JOBS 8
  56
  57#define dprintk(fdp1, fmt, arg...) \
  58	v4l2_dbg(1, debug, &fdp1->v4l2_dev, "%s: " fmt, __func__, ## arg)
  59
  60/*
  61 * FDP1 registers and bits
  62 */
  63
  64/* FDP1 start register - Imm */
  65#define FD1_CTL_CMD			0x0000
  66#define FD1_CTL_CMD_STRCMD		BIT(0)
  67
  68/* Sync generator register - Imm */
  69#define FD1_CTL_SGCMD			0x0004
  70#define FD1_CTL_SGCMD_SGEN		BIT(0)
  71
  72/* Register set end register - Imm */
  73#define FD1_CTL_REGEND			0x0008
  74#define FD1_CTL_REGEND_REGEND		BIT(0)
  75
  76/* Channel activation register - Vupdt */
  77#define FD1_CTL_CHACT			0x000c
  78#define FD1_CTL_CHACT_SMW		BIT(9)
  79#define FD1_CTL_CHACT_WR		BIT(8)
  80#define FD1_CTL_CHACT_SMR		BIT(3)
  81#define FD1_CTL_CHACT_RD2		BIT(2)
  82#define FD1_CTL_CHACT_RD1		BIT(1)
  83#define FD1_CTL_CHACT_RD0		BIT(0)
  84
  85/* Operation Mode Register - Vupdt */
  86#define FD1_CTL_OPMODE			0x0010
  87#define FD1_CTL_OPMODE_PRG		BIT(4)
  88#define FD1_CTL_OPMODE_VIMD_INTERRUPT	(0 << 0)
  89#define FD1_CTL_OPMODE_VIMD_BESTEFFORT	(1 << 0)
  90#define FD1_CTL_OPMODE_VIMD_NOINTERRUPT	(2 << 0)
  91
  92#define FD1_CTL_VPERIOD			0x0014
  93#define FD1_CTL_CLKCTRL			0x0018
  94#define FD1_CTL_CLKCTRL_CSTP_N		BIT(0)
  95
  96/* Software reset register */
  97#define FD1_CTL_SRESET			0x001c
  98#define FD1_CTL_SRESET_SRST		BIT(0)
  99
 100/* Control status register (V-update-status) */
 101#define FD1_CTL_STATUS			0x0024
 102#define FD1_CTL_STATUS_VINT_CNT_MASK	GENMASK(31, 16)
 103#define FD1_CTL_STATUS_VINT_CNT_SHIFT	16
 104#define FD1_CTL_STATUS_SGREGSET		BIT(10)
 105#define FD1_CTL_STATUS_SGVERR		BIT(9)
 106#define FD1_CTL_STATUS_SGFREND		BIT(8)
 107#define FD1_CTL_STATUS_BSY		BIT(0)
 108
 109#define FD1_CTL_VCYCLE_STAT		0x0028
 110
 111/* Interrupt enable register */
 112#define FD1_CTL_IRQENB			0x0038
 113/* Interrupt status register */
 114#define FD1_CTL_IRQSTA			0x003c
 115/* Interrupt control register */
 116#define FD1_CTL_IRQFSET			0x0040
 117
 118/* Common IRQ Bit settings */
 119#define FD1_CTL_IRQ_VERE		BIT(16)
 120#define FD1_CTL_IRQ_VINTE		BIT(4)
 121#define FD1_CTL_IRQ_FREE		BIT(0)
 122#define FD1_CTL_IRQ_MASK		(FD1_CTL_IRQ_VERE | \
 123					 FD1_CTL_IRQ_VINTE | \
 124					 FD1_CTL_IRQ_FREE)
 125
 126/* RPF */
 127#define FD1_RPF_SIZE			0x0060
 128#define FD1_RPF_SIZE_MASK		GENMASK(12, 0)
 129#define FD1_RPF_SIZE_H_SHIFT		16
 130#define FD1_RPF_SIZE_V_SHIFT		0
 131
 132#define FD1_RPF_FORMAT			0x0064
 133#define FD1_RPF_FORMAT_CIPM		BIT(16)
 134#define FD1_RPF_FORMAT_RSPYCS		BIT(13)
 135#define FD1_RPF_FORMAT_RSPUVS		BIT(12)
 136#define FD1_RPF_FORMAT_CF		BIT(8)
 137
 138#define FD1_RPF_PSTRIDE			0x0068
 139#define FD1_RPF_PSTRIDE_Y_SHIFT		16
 140#define FD1_RPF_PSTRIDE_C_SHIFT		0
 141
 142/* RPF0 Source Component Y Address register */
 143#define FD1_RPF0_ADDR_Y			0x006c
 144
 145/* RPF1 Current Picture Registers */
 146#define FD1_RPF1_ADDR_Y			0x0078
 147#define FD1_RPF1_ADDR_C0		0x007c
 148#define FD1_RPF1_ADDR_C1		0x0080
 149
 150/* RPF2 next picture register */
 151#define FD1_RPF2_ADDR_Y			0x0084
 152
 153#define FD1_RPF_SMSK_ADDR		0x0090
 154#define FD1_RPF_SWAP			0x0094
 155
 156/* WPF */
 157#define FD1_WPF_FORMAT			0x00c0
 158#define FD1_WPF_FORMAT_PDV_SHIFT	24
 159#define FD1_WPF_FORMAT_FCNL		BIT(20)
 160#define FD1_WPF_FORMAT_WSPYCS		BIT(15)
 161#define FD1_WPF_FORMAT_WSPUVS		BIT(14)
 162#define FD1_WPF_FORMAT_WRTM_601_16	(0 << 9)
 163#define FD1_WPF_FORMAT_WRTM_601_0	(1 << 9)
 164#define FD1_WPF_FORMAT_WRTM_709_16	(2 << 9)
 165#define FD1_WPF_FORMAT_CSC		BIT(8)
 166
 167#define FD1_WPF_RNDCTL			0x00c4
 168#define FD1_WPF_RNDCTL_CBRM		BIT(28)
 169#define FD1_WPF_RNDCTL_CLMD_NOCLIP	(0 << 12)
 170#define FD1_WPF_RNDCTL_CLMD_CLIP_16_235	(1 << 12)
 171#define FD1_WPF_RNDCTL_CLMD_CLIP_1_254	(2 << 12)
 172
 173#define FD1_WPF_PSTRIDE			0x00c8
 174#define FD1_WPF_PSTRIDE_Y_SHIFT		16
 175#define FD1_WPF_PSTRIDE_C_SHIFT		0
 176
 177/* WPF Destination picture */
 178#define FD1_WPF_ADDR_Y			0x00cc
 179#define FD1_WPF_ADDR_C0			0x00d0
 180#define FD1_WPF_ADDR_C1			0x00d4
 181#define FD1_WPF_SWAP			0x00d8
 182#define FD1_WPF_SWAP_OSWAP_SHIFT	0
 183#define FD1_WPF_SWAP_SSWAP_SHIFT	4
 184
 185/* WPF/RPF Common */
 186#define FD1_RWPF_SWAP_BYTE		BIT(0)
 187#define FD1_RWPF_SWAP_WORD		BIT(1)
 188#define FD1_RWPF_SWAP_LWRD		BIT(2)
 189#define FD1_RWPF_SWAP_LLWD		BIT(3)
 190
 191/* IPC */
 192#define FD1_IPC_MODE			0x0100
 193#define FD1_IPC_MODE_DLI		BIT(8)
 194#define FD1_IPC_MODE_DIM_ADAPT2D3D	(0 << 0)
 195#define FD1_IPC_MODE_DIM_FIXED2D	(1 << 0)
 196#define FD1_IPC_MODE_DIM_FIXED3D	(2 << 0)
 197#define FD1_IPC_MODE_DIM_PREVFIELD	(3 << 0)
 198#define FD1_IPC_MODE_DIM_NEXTFIELD	(4 << 0)
 199
 200#define FD1_IPC_SMSK_THRESH		0x0104
 201#define FD1_IPC_SMSK_THRESH_CONST	0x00010002
 202
 203#define FD1_IPC_COMB_DET		0x0108
 204#define FD1_IPC_COMB_DET_CONST		0x00200040
 205
 206#define FD1_IPC_MOTDEC			0x010c
 207#define FD1_IPC_MOTDEC_CONST		0x00008020
 208
 209/* DLI registers */
 210#define FD1_IPC_DLI_BLEND		0x0120
 211#define FD1_IPC_DLI_BLEND_CONST		0x0080ff02
 212
 213#define FD1_IPC_DLI_HGAIN		0x0124
 214#define FD1_IPC_DLI_HGAIN_CONST		0x001000ff
 215
 216#define FD1_IPC_DLI_SPRS		0x0128
 217#define FD1_IPC_DLI_SPRS_CONST		0x009004ff
 218
 219#define FD1_IPC_DLI_ANGLE		0x012c
 220#define FD1_IPC_DLI_ANGLE_CONST		0x0004080c
 221
 222#define FD1_IPC_DLI_ISOPIX0		0x0130
 223#define FD1_IPC_DLI_ISOPIX0_CONST	0xff10ff10
 224
 225#define FD1_IPC_DLI_ISOPIX1		0x0134
 226#define FD1_IPC_DLI_ISOPIX1_CONST	0x0000ff10
 227
 228/* Sensor registers */
 229#define FD1_IPC_SENSOR_TH0		0x0140
 230#define FD1_IPC_SENSOR_TH0_CONST	0x20208080
 231
 232#define FD1_IPC_SENSOR_TH1		0x0144
 233#define FD1_IPC_SENSOR_TH1_CONST	0
 234
 235#define FD1_IPC_SENSOR_CTL0		0x0170
 236#define FD1_IPC_SENSOR_CTL0_CONST	0x00002201
 237
 238#define FD1_IPC_SENSOR_CTL1		0x0174
 239#define FD1_IPC_SENSOR_CTL1_CONST	0
 240
 241#define FD1_IPC_SENSOR_CTL2		0x0178
 242#define FD1_IPC_SENSOR_CTL2_X_SHIFT	16
 243#define FD1_IPC_SENSOR_CTL2_Y_SHIFT	0
 244
 245#define FD1_IPC_SENSOR_CTL3		0x017c
 246#define FD1_IPC_SENSOR_CTL3_0_SHIFT	16
 247#define FD1_IPC_SENSOR_CTL3_1_SHIFT	0
 248
 249/* Line memory pixel number register */
 250#define FD1_IPC_LMEM			0x01e0
 251#define FD1_IPC_LMEM_LINEAR		1024
 252#define FD1_IPC_LMEM_TILE		960
 253
 254/* Internal Data (HW Version) */
 255#define FD1_IP_INTDATA			0x0800
 256/* R-Car Gen2 HW manual says zero, but actual value matches R-Car H3 ES1.x */
 257#define FD1_IP_GEN2			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 *file_to_ctx(struct file *filp)
 634{
 635	return container_of(file_to_v4l2_fh(filp), 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_ctx *ctx = file_to_ctx(file);
1410	struct fdp1_q_data *q_data;
1411
1412	q_data = get_q_data(ctx, f->type);
1413	f->fmt.pix_mp = q_data->format;
1414
1415	return 0;
1416}
1417
1418static void fdp1_compute_stride(struct v4l2_pix_format_mplane *pix,
1419				const struct fdp1_fmt *fmt)
1420{
1421	unsigned int i;
1422
1423	/* Compute and clamp the stride and image size. */
1424	for (i = 0; i < min_t(unsigned int, fmt->num_planes, 2U); ++i) {
1425		unsigned int hsub = i > 0 ? fmt->hsub : 1;
1426		unsigned int vsub = i > 0 ? fmt->vsub : 1;
1427		 /* From VSP : TODO: Confirm alignment limits for FDP1 */
1428		unsigned int align = 128;
1429		unsigned int bpl;
1430
1431		bpl = clamp_t(unsigned int, pix->plane_fmt[i].bytesperline,
1432			      pix->width / hsub * fmt->bpp[i] / 8,
1433			      round_down(FDP1_MAX_STRIDE, align));
1434
1435		pix->plane_fmt[i].bytesperline = round_up(bpl, align);
1436		pix->plane_fmt[i].sizeimage = pix->plane_fmt[i].bytesperline
1437					    * pix->height / vsub;
1438
1439	}
1440
1441	if (fmt->num_planes == 3) {
1442		/* The two chroma planes must have the same stride. */
1443		pix->plane_fmt[2].bytesperline = pix->plane_fmt[1].bytesperline;
1444		pix->plane_fmt[2].sizeimage = pix->plane_fmt[1].sizeimage;
1445
1446	}
1447}
1448
1449static void fdp1_try_fmt_output(struct fdp1_ctx *ctx,
1450				const struct fdp1_fmt **fmtinfo,
1451				struct v4l2_pix_format_mplane *pix)
1452{
1453	const struct fdp1_fmt *fmt;
1454	unsigned int width;
1455	unsigned int height;
1456
1457	/* Validate the pixel format to ensure the output queue supports it. */
1458	fmt = fdp1_find_format(pix->pixelformat);
1459	if (!fmt || !(fmt->types & FDP1_OUTPUT))
1460		fmt = fdp1_find_format(V4L2_PIX_FMT_YUYV);
1461
1462	if (fmtinfo)
1463		*fmtinfo = fmt;
1464
1465	pix->pixelformat = fmt->fourcc;
1466	pix->num_planes = fmt->num_planes;
1467
1468	/*
1469	 * Progressive video and all interlaced field orders are acceptable.
1470	 * Default to V4L2_FIELD_INTERLACED.
1471	 */
1472	if (pix->field != V4L2_FIELD_NONE &&
1473	    pix->field != V4L2_FIELD_ALTERNATE &&
1474	    !V4L2_FIELD_HAS_BOTH(pix->field))
1475		pix->field = V4L2_FIELD_INTERLACED;
1476
1477	/*
1478	 * The deinterlacer doesn't care about the colorspace, accept all values
1479	 * and default to V4L2_COLORSPACE_SMPTE170M. The YUV to RGB conversion
1480	 * at the output of the deinterlacer supports a subset of encodings and
1481	 * quantization methods and will only be available when the colorspace
1482	 * allows it.
1483	 */
1484	if (pix->colorspace == V4L2_COLORSPACE_DEFAULT)
1485		pix->colorspace = V4L2_COLORSPACE_SMPTE170M;
1486
1487	/*
1488	 * Align the width and height for YUV 4:2:2 and 4:2:0 formats and clamp
1489	 * them to the supported frame size range. The height boundary are
1490	 * related to the full frame, divide them by two when the format passes
1491	 * fields in separate buffers.
1492	 */
1493	width = round_down(pix->width, fmt->hsub);
1494	pix->width = clamp(width, FDP1_MIN_W, FDP1_MAX_W);
1495
1496	height = round_down(pix->height, fmt->vsub);
1497	if (pix->field == V4L2_FIELD_ALTERNATE)
1498		pix->height = clamp(height, FDP1_MIN_H / 2, FDP1_MAX_H / 2);
1499	else
1500		pix->height = clamp(height, FDP1_MIN_H, FDP1_MAX_H);
1501
1502	fdp1_compute_stride(pix, fmt);
1503}
1504
1505static void fdp1_try_fmt_capture(struct fdp1_ctx *ctx,
1506				 const struct fdp1_fmt **fmtinfo,
1507				 struct v4l2_pix_format_mplane *pix)
1508{
1509	struct fdp1_q_data *src_data = &ctx->out_q;
1510	enum v4l2_colorspace colorspace;
1511	enum v4l2_ycbcr_encoding ycbcr_enc;
1512	enum v4l2_quantization quantization;
1513	const struct fdp1_fmt *fmt;
1514	bool allow_rgb;
1515
1516	/*
1517	 * Validate the pixel format. We can only accept RGB output formats if
1518	 * the input encoding and quantization are compatible with the format
1519	 * conversions supported by the hardware. The supported combinations are
1520	 *
1521	 * V4L2_YCBCR_ENC_601 + V4L2_QUANTIZATION_LIM_RANGE
1522	 * V4L2_YCBCR_ENC_601 + V4L2_QUANTIZATION_FULL_RANGE
1523	 * V4L2_YCBCR_ENC_709 + V4L2_QUANTIZATION_LIM_RANGE
1524	 */
1525	colorspace = src_data->format.colorspace;
1526
1527	ycbcr_enc = src_data->format.ycbcr_enc;
1528	if (ycbcr_enc == V4L2_YCBCR_ENC_DEFAULT)
1529		ycbcr_enc = V4L2_MAP_YCBCR_ENC_DEFAULT(colorspace);
1530
1531	quantization = src_data->format.quantization;
1532	if (quantization == V4L2_QUANTIZATION_DEFAULT)
1533		quantization = V4L2_MAP_QUANTIZATION_DEFAULT(false, colorspace,
1534							     ycbcr_enc);
1535
1536	allow_rgb = ycbcr_enc == V4L2_YCBCR_ENC_601 ||
1537		    (ycbcr_enc == V4L2_YCBCR_ENC_709 &&
1538		     quantization == V4L2_QUANTIZATION_LIM_RANGE);
1539
1540	fmt = fdp1_find_format(pix->pixelformat);
1541	if (!fmt || (!allow_rgb && fdp1_fmt_is_rgb(fmt)))
1542		fmt = fdp1_find_format(V4L2_PIX_FMT_YUYV);
1543
1544	if (fmtinfo)
1545		*fmtinfo = fmt;
1546
1547	pix->pixelformat = fmt->fourcc;
1548	pix->num_planes = fmt->num_planes;
1549	pix->field = V4L2_FIELD_NONE;
1550
1551	/*
1552	 * The colorspace on the capture queue is copied from the output queue
1553	 * as the hardware can't change the colorspace. It can convert YCbCr to
1554	 * RGB though, in which case the encoding and quantization are set to
1555	 * default values as anything else wouldn't make sense.
1556	 */
1557	pix->colorspace = src_data->format.colorspace;
1558	pix->xfer_func = src_data->format.xfer_func;
1559
1560	if (fdp1_fmt_is_rgb(fmt)) {
1561		pix->ycbcr_enc = V4L2_YCBCR_ENC_DEFAULT;
1562		pix->quantization = V4L2_QUANTIZATION_DEFAULT;
1563	} else {
1564		pix->ycbcr_enc = src_data->format.ycbcr_enc;
1565		pix->quantization = src_data->format.quantization;
1566	}
1567
1568	/*
1569	 * The frame width is identical to the output queue, and the height is
1570	 * either doubled or identical depending on whether the output queue
1571	 * field order contains one or two fields per frame.
1572	 */
1573	pix->width = src_data->format.width;
1574	if (src_data->format.field == V4L2_FIELD_ALTERNATE)
1575		pix->height = 2 * src_data->format.height;
1576	else
1577		pix->height = src_data->format.height;
1578
1579	fdp1_compute_stride(pix, fmt);
1580}
1581
1582static int fdp1_try_fmt(struct file *file, void *priv, struct v4l2_format *f)
1583{
1584	struct fdp1_ctx *ctx = file_to_ctx(file);
1585
1586	if (f->type == V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE)
1587		fdp1_try_fmt_output(ctx, NULL, &f->fmt.pix_mp);
1588	else
1589		fdp1_try_fmt_capture(ctx, NULL, &f->fmt.pix_mp);
1590
1591	dprintk(ctx->fdp1, "Try %s format: %4.4s (0x%08x) %ux%u field %u\n",
1592		V4L2_TYPE_IS_OUTPUT(f->type) ? "output" : "capture",
1593		(char *)&f->fmt.pix_mp.pixelformat, f->fmt.pix_mp.pixelformat,
1594		f->fmt.pix_mp.width, f->fmt.pix_mp.height, f->fmt.pix_mp.field);
1595
1596	return 0;
1597}
1598
1599static void fdp1_set_format(struct fdp1_ctx *ctx,
1600			    struct v4l2_pix_format_mplane *pix,
1601			    enum v4l2_buf_type type)
1602{
1603	struct fdp1_q_data *q_data = get_q_data(ctx, type);
1604	const struct fdp1_fmt *fmtinfo;
1605
1606	if (type == V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE)
1607		fdp1_try_fmt_output(ctx, &fmtinfo, pix);
1608	else
1609		fdp1_try_fmt_capture(ctx, &fmtinfo, pix);
1610
1611	q_data->fmt = fmtinfo;
1612	q_data->format = *pix;
1613
1614	q_data->vsize = pix->height;
1615	if (pix->field != V4L2_FIELD_NONE)
1616		q_data->vsize /= 2;
1617
1618	q_data->stride_y = pix->plane_fmt[0].bytesperline;
1619	q_data->stride_c = pix->plane_fmt[1].bytesperline;
1620
1621	/* Adjust strides for interleaved buffers */
1622	if (pix->field == V4L2_FIELD_INTERLACED ||
1623	    pix->field == V4L2_FIELD_INTERLACED_TB ||
1624	    pix->field == V4L2_FIELD_INTERLACED_BT) {
1625		q_data->stride_y *= 2;
1626		q_data->stride_c *= 2;
1627	}
1628
1629	/* Propagate the format from the output node to the capture node. */
1630	if (type == V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE) {
1631		struct fdp1_q_data *dst_data = &ctx->cap_q;
1632
1633		/*
1634		 * Copy the format, clear the per-plane bytes per line and image
1635		 * size, override the field and double the height if needed.
1636		 */
1637		dst_data->format = q_data->format;
1638		memset(dst_data->format.plane_fmt, 0,
1639		       sizeof(dst_data->format.plane_fmt));
1640
1641		dst_data->format.field = V4L2_FIELD_NONE;
1642		if (pix->field == V4L2_FIELD_ALTERNATE)
1643			dst_data->format.height *= 2;
1644
1645		fdp1_try_fmt_capture(ctx, &dst_data->fmt, &dst_data->format);
1646
1647		dst_data->vsize = dst_data->format.height;
1648		dst_data->stride_y = dst_data->format.plane_fmt[0].bytesperline;
1649		dst_data->stride_c = dst_data->format.plane_fmt[1].bytesperline;
1650	}
1651}
1652
1653static int fdp1_s_fmt(struct file *file, void *priv, struct v4l2_format *f)
1654{
1655	struct fdp1_ctx *ctx = file_to_ctx(file);
1656	struct v4l2_m2m_ctx *m2m_ctx = ctx->fh.m2m_ctx;
1657	struct vb2_queue *vq = v4l2_m2m_get_vq(m2m_ctx, f->type);
1658
1659	if (vb2_is_busy(vq)) {
1660		v4l2_err(&ctx->fdp1->v4l2_dev, "%s queue busy\n", __func__);
1661		return -EBUSY;
1662	}
1663
1664	fdp1_set_format(ctx, &f->fmt.pix_mp, f->type);
1665
1666	dprintk(ctx->fdp1, "Set %s format: %4.4s (0x%08x) %ux%u field %u\n",
1667		V4L2_TYPE_IS_OUTPUT(f->type) ? "output" : "capture",
1668		(char *)&f->fmt.pix_mp.pixelformat, f->fmt.pix_mp.pixelformat,
1669		f->fmt.pix_mp.width, f->fmt.pix_mp.height, f->fmt.pix_mp.field);
1670
1671	return 0;
1672}
1673
1674static int fdp1_g_ctrl(struct v4l2_ctrl *ctrl)
1675{
1676	struct fdp1_ctx *ctx =
1677		container_of(ctrl->handler, struct fdp1_ctx, hdl);
1678	struct fdp1_q_data *src_q_data = &ctx->out_q;
1679
1680	switch (ctrl->id) {
1681	case V4L2_CID_MIN_BUFFERS_FOR_CAPTURE:
1682		if (V4L2_FIELD_HAS_BOTH(src_q_data->format.field))
1683			ctrl->val = 2;
1684		else
1685			ctrl->val = 1;
1686		return 0;
1687	}
1688
1689	return 1;
1690}
1691
1692static int fdp1_s_ctrl(struct v4l2_ctrl *ctrl)
1693{
1694	struct fdp1_ctx *ctx =
1695		container_of(ctrl->handler, struct fdp1_ctx, hdl);
1696
1697	switch (ctrl->id) {
1698	case V4L2_CID_ALPHA_COMPONENT:
1699		ctx->alpha = ctrl->val;
1700		break;
1701
1702	case V4L2_CID_DEINTERLACING_MODE:
1703		ctx->deint_mode = ctrl->val;
1704		break;
1705	}
1706
1707	return 0;
1708}
1709
1710static const struct v4l2_ctrl_ops fdp1_ctrl_ops = {
1711	.s_ctrl = fdp1_s_ctrl,
1712	.g_volatile_ctrl = fdp1_g_ctrl,
1713};
1714
1715static const char * const fdp1_ctrl_deint_menu[] = {
1716	"Progressive",
1717	"Adaptive 2D/3D",
1718	"Fixed 2D",
1719	"Fixed 3D",
1720	"Previous field",
1721	"Next field",
1722	NULL
1723};
1724
1725static const struct v4l2_ioctl_ops fdp1_ioctl_ops = {
1726	.vidioc_querycap	= fdp1_vidioc_querycap,
1727
1728	.vidioc_enum_fmt_vid_cap	= fdp1_enum_fmt_vid_cap,
1729	.vidioc_enum_fmt_vid_out	= fdp1_enum_fmt_vid_out,
1730	.vidioc_g_fmt_vid_cap_mplane	= fdp1_g_fmt,
1731	.vidioc_g_fmt_vid_out_mplane	= fdp1_g_fmt,
1732	.vidioc_try_fmt_vid_cap_mplane	= fdp1_try_fmt,
1733	.vidioc_try_fmt_vid_out_mplane	= fdp1_try_fmt,
1734	.vidioc_s_fmt_vid_cap_mplane	= fdp1_s_fmt,
1735	.vidioc_s_fmt_vid_out_mplane	= fdp1_s_fmt,
1736
1737	.vidioc_reqbufs		= v4l2_m2m_ioctl_reqbufs,
1738	.vidioc_querybuf	= v4l2_m2m_ioctl_querybuf,
1739	.vidioc_qbuf		= v4l2_m2m_ioctl_qbuf,
1740	.vidioc_dqbuf		= v4l2_m2m_ioctl_dqbuf,
1741	.vidioc_prepare_buf	= v4l2_m2m_ioctl_prepare_buf,
1742	.vidioc_create_bufs	= v4l2_m2m_ioctl_create_bufs,
1743	.vidioc_expbuf		= v4l2_m2m_ioctl_expbuf,
1744
1745	.vidioc_streamon	= v4l2_m2m_ioctl_streamon,
1746	.vidioc_streamoff	= v4l2_m2m_ioctl_streamoff,
1747
1748	.vidioc_subscribe_event = v4l2_ctrl_subscribe_event,
1749	.vidioc_unsubscribe_event = v4l2_event_unsubscribe,
1750};
1751
1752/*
1753 * Queue operations
1754 */
1755
1756static int fdp1_queue_setup(struct vb2_queue *vq,
1757				unsigned int *nbuffers, unsigned int *nplanes,
1758				unsigned int sizes[],
1759				struct device *alloc_ctxs[])
1760{
1761	struct fdp1_ctx *ctx = vb2_get_drv_priv(vq);
1762	struct fdp1_q_data *q_data;
1763	unsigned int i;
1764
1765	q_data = get_q_data(ctx, vq->type);
1766
1767	if (*nplanes) {
1768		if (*nplanes > FDP1_MAX_PLANES)
1769			return -EINVAL;
1770
1771		return 0;
1772	}
1773
1774	*nplanes = q_data->format.num_planes;
1775
1776	for (i = 0; i < *nplanes; i++)
1777		sizes[i] = q_data->format.plane_fmt[i].sizeimage;
1778
1779	return 0;
1780}
1781
1782static void fdp1_buf_prepare_field(struct fdp1_q_data *q_data,
1783				   struct vb2_v4l2_buffer *vbuf,
1784				   unsigned int field_num)
1785{
1786	struct fdp1_buffer *buf = to_fdp1_buffer(vbuf);
1787	struct fdp1_field_buffer *fbuf = &buf->fields[field_num];
1788	unsigned int num_fields;
1789	unsigned int i;
1790
1791	num_fields = V4L2_FIELD_HAS_BOTH(vbuf->field) ? 2 : 1;
1792
1793	fbuf->vb = vbuf;
1794	fbuf->last_field = (field_num + 1) == num_fields;
1795
1796	for (i = 0; i < vbuf->vb2_buf.num_planes; ++i)
1797		fbuf->addrs[i] = vb2_dma_contig_plane_dma_addr(&vbuf->vb2_buf, i);
1798
1799	switch (vbuf->field) {
1800	case V4L2_FIELD_INTERLACED:
1801		/*
1802		 * Interlaced means bottom-top for 60Hz TV standards (NTSC) and
1803		 * top-bottom for 50Hz. As TV standards are not applicable to
1804		 * the mem-to-mem API, use the height as a heuristic.
1805		 */
1806		fbuf->field = (q_data->format.height < 576) == field_num
1807			    ? V4L2_FIELD_TOP : V4L2_FIELD_BOTTOM;
1808		break;
1809	case V4L2_FIELD_INTERLACED_TB:
1810	case V4L2_FIELD_SEQ_TB:
1811		fbuf->field = field_num ? V4L2_FIELD_BOTTOM : V4L2_FIELD_TOP;
1812		break;
1813	case V4L2_FIELD_INTERLACED_BT:
1814	case V4L2_FIELD_SEQ_BT:
1815		fbuf->field = field_num ? V4L2_FIELD_TOP : V4L2_FIELD_BOTTOM;
1816		break;
1817	default:
1818		fbuf->field = vbuf->field;
1819		break;
1820	}
1821
1822	/* Buffer is completed */
1823	if (!field_num)
1824		return;
1825
1826	/* Adjust buffer addresses for second field */
1827	switch (vbuf->field) {
1828	case V4L2_FIELD_INTERLACED:
1829	case V4L2_FIELD_INTERLACED_TB:
1830	case V4L2_FIELD_INTERLACED_BT:
1831		for (i = 0; i < vbuf->vb2_buf.num_planes; i++)
1832			fbuf->addrs[i] +=
1833				(i == 0 ? q_data->stride_y : q_data->stride_c);
1834		break;
1835	case V4L2_FIELD_SEQ_TB:
1836	case V4L2_FIELD_SEQ_BT:
1837		for (i = 0; i < vbuf->vb2_buf.num_planes; i++)
1838			fbuf->addrs[i] += q_data->vsize *
1839				(i == 0 ? q_data->stride_y : q_data->stride_c);
1840		break;
1841	}
1842}
1843
1844static int fdp1_buf_prepare(struct vb2_buffer *vb)
1845{
1846	struct fdp1_ctx *ctx = vb2_get_drv_priv(vb->vb2_queue);
1847	struct fdp1_q_data *q_data = get_q_data(ctx, vb->vb2_queue->type);
1848	struct vb2_v4l2_buffer *vbuf = to_vb2_v4l2_buffer(vb);
1849	struct fdp1_buffer *buf = to_fdp1_buffer(vbuf);
1850	unsigned int i;
1851
1852	if (V4L2_TYPE_IS_OUTPUT(vb->vb2_queue->type)) {
1853		bool field_valid = true;
1854
1855		/* Validate the buffer field. */
1856		switch (q_data->format.field) {
1857		case V4L2_FIELD_NONE:
1858			if (vbuf->field != V4L2_FIELD_NONE)
1859				field_valid = false;
1860			break;
1861
1862		case V4L2_FIELD_ALTERNATE:
1863			if (vbuf->field != V4L2_FIELD_TOP &&
1864			    vbuf->field != V4L2_FIELD_BOTTOM)
1865				field_valid = false;
1866			break;
1867
1868		case V4L2_FIELD_INTERLACED:
1869		case V4L2_FIELD_SEQ_TB:
1870		case V4L2_FIELD_SEQ_BT:
1871		case V4L2_FIELD_INTERLACED_TB:
1872		case V4L2_FIELD_INTERLACED_BT:
1873			if (vbuf->field != q_data->format.field)
1874				field_valid = false;
1875			break;
1876		}
1877
1878		if (!field_valid) {
1879			dprintk(ctx->fdp1,
1880				"buffer field %u invalid for format field %u\n",
1881				vbuf->field, q_data->format.field);
1882			return -EINVAL;
1883		}
1884	} else {
1885		vbuf->field = V4L2_FIELD_NONE;
1886	}
1887
1888	/* Validate the planes sizes. */
1889	for (i = 0; i < q_data->format.num_planes; i++) {
1890		unsigned long size = q_data->format.plane_fmt[i].sizeimage;
1891
1892		if (vb2_plane_size(vb, i) < size) {
1893			dprintk(ctx->fdp1,
1894				"data will not fit into plane [%u/%u] (%lu < %lu)\n",
1895				i, q_data->format.num_planes,
1896				vb2_plane_size(vb, i), size);
1897			return -EINVAL;
1898		}
1899
1900		/* We have known size formats all around */
1901		vb2_set_plane_payload(vb, i, size);
1902	}
1903
1904	buf->num_fields = V4L2_FIELD_HAS_BOTH(vbuf->field) ? 2 : 1;
1905	for (i = 0; i < buf->num_fields; ++i)
1906		fdp1_buf_prepare_field(q_data, vbuf, i);
1907
1908	return 0;
1909}
1910
1911static void fdp1_buf_queue(struct vb2_buffer *vb)
1912{
1913	struct vb2_v4l2_buffer *vbuf = to_vb2_v4l2_buffer(vb);
1914	struct fdp1_ctx *ctx = vb2_get_drv_priv(vb->vb2_queue);
1915
1916	v4l2_m2m_buf_queue(ctx->fh.m2m_ctx, vbuf);
1917}
1918
1919static int fdp1_start_streaming(struct vb2_queue *q, unsigned int count)
1920{
1921	struct fdp1_ctx *ctx = vb2_get_drv_priv(q);
1922	struct fdp1_q_data *q_data = get_q_data(ctx, q->type);
1923
1924	if (V4L2_TYPE_IS_OUTPUT(q->type)) {
1925		/*
1926		 * Force our deint_mode when we are progressive,
1927		 * ignoring any setting on the device from the user,
1928		 * Otherwise, lock in the requested de-interlace mode.
1929		 */
1930		if (q_data->format.field == V4L2_FIELD_NONE)
1931			ctx->deint_mode = FDP1_PROGRESSIVE;
1932
1933		if (ctx->deint_mode == FDP1_ADAPT2D3D) {
1934			u32 stride;
1935			dma_addr_t smsk_base;
1936			const u32 bpp = 2; /* bytes per pixel */
1937
1938			stride = round_up(q_data->format.width, 8);
1939
1940			ctx->smsk_size = bpp * stride * q_data->vsize;
1941
1942			ctx->smsk_cpu = dma_alloc_coherent(ctx->fdp1->dev,
1943				ctx->smsk_size, &smsk_base, GFP_KERNEL);
1944
1945			if (ctx->smsk_cpu == NULL) {
1946				dprintk(ctx->fdp1, "Failed to alloc smsk\n");
1947				return -ENOMEM;
1948			}
1949
1950			ctx->smsk_addr[0] = smsk_base;
1951			ctx->smsk_addr[1] = smsk_base + (ctx->smsk_size/2);
1952		}
1953	}
1954
1955	return 0;
1956}
1957
1958static void fdp1_stop_streaming(struct vb2_queue *q)
1959{
1960	struct fdp1_ctx *ctx = vb2_get_drv_priv(q);
1961	struct vb2_v4l2_buffer *vbuf;
1962	unsigned long flags;
1963
1964	while (1) {
1965		if (V4L2_TYPE_IS_OUTPUT(q->type))
1966			vbuf = v4l2_m2m_src_buf_remove(ctx->fh.m2m_ctx);
1967		else
1968			vbuf = v4l2_m2m_dst_buf_remove(ctx->fh.m2m_ctx);
1969		if (vbuf == NULL)
1970			break;
1971		spin_lock_irqsave(&ctx->fdp1->irqlock, flags);
1972		v4l2_m2m_buf_done(vbuf, VB2_BUF_STATE_ERROR);
1973		spin_unlock_irqrestore(&ctx->fdp1->irqlock, flags);
1974	}
1975
1976	/* Empty Output queues */
1977	if (V4L2_TYPE_IS_OUTPUT(q->type)) {
1978		/* Empty our internal queues */
1979		struct fdp1_field_buffer *fbuf;
1980
1981		/* Free any queued buffers */
1982		fbuf = fdp1_dequeue_field(ctx);
1983		while (fbuf != NULL) {
1984			fdp1_field_complete(ctx, fbuf);
1985			fbuf = fdp1_dequeue_field(ctx);
1986		}
1987
1988		/* Free smsk_data */
1989		if (ctx->smsk_cpu) {
1990			dma_free_coherent(ctx->fdp1->dev, ctx->smsk_size,
1991					  ctx->smsk_cpu, ctx->smsk_addr[0]);
1992			ctx->smsk_addr[0] = ctx->smsk_addr[1] = 0;
1993			ctx->smsk_cpu = NULL;
1994		}
1995
1996		WARN(!list_empty(&ctx->fields_queue),
1997		     "Buffer queue not empty");
1998	} else {
1999		/* Empty Capture queues (Jobs) */
2000		struct fdp1_job *job;
2001
2002		job = get_queued_job(ctx->fdp1);
2003		while (job) {
2004			if (FDP1_DEINT_MODE_USES_PREV(ctx->deint_mode))
2005				fdp1_field_complete(ctx, job->previous);
2006			else
2007				fdp1_field_complete(ctx, job->active);
2008
2009			v4l2_m2m_buf_done(job->dst->vb, VB2_BUF_STATE_ERROR);
2010			job->dst = NULL;
2011
2012			job = get_queued_job(ctx->fdp1);
2013		}
2014
2015		/* Free any held buffer in the ctx */
2016		fdp1_field_complete(ctx, ctx->previous);
2017
2018		WARN(!list_empty(&ctx->fdp1->queued_job_list),
2019		     "Queued Job List not empty");
2020
2021		WARN(!list_empty(&ctx->fdp1->hw_job_list),
2022		     "HW Job list not empty");
2023	}
2024}
2025
2026static const struct vb2_ops fdp1_qops = {
2027	.queue_setup	 = fdp1_queue_setup,
2028	.buf_prepare	 = fdp1_buf_prepare,
2029	.buf_queue	 = fdp1_buf_queue,
2030	.start_streaming = fdp1_start_streaming,
2031	.stop_streaming  = fdp1_stop_streaming,
2032};
2033
2034static int queue_init(void *priv, struct vb2_queue *src_vq,
2035		      struct vb2_queue *dst_vq)
2036{
2037	struct fdp1_ctx *ctx = priv;
2038	int ret;
2039
2040	src_vq->type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE;
2041	src_vq->io_modes = VB2_MMAP | VB2_USERPTR | VB2_DMABUF;
2042	src_vq->drv_priv = ctx;
2043	src_vq->buf_struct_size = sizeof(struct fdp1_buffer);
2044	src_vq->ops = &fdp1_qops;
2045	src_vq->mem_ops = &vb2_dma_contig_memops;
2046	src_vq->timestamp_flags = V4L2_BUF_FLAG_TIMESTAMP_COPY;
2047	src_vq->lock = &ctx->fdp1->dev_mutex;
2048	src_vq->dev = ctx->fdp1->dev;
2049
2050	ret = vb2_queue_init(src_vq);
2051	if (ret)
2052		return ret;
2053
2054	dst_vq->type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
2055	dst_vq->io_modes = VB2_MMAP | VB2_USERPTR | VB2_DMABUF;
2056	dst_vq->drv_priv = ctx;
2057	dst_vq->buf_struct_size = sizeof(struct fdp1_buffer);
2058	dst_vq->ops = &fdp1_qops;
2059	dst_vq->mem_ops = &vb2_dma_contig_memops;
2060	dst_vq->timestamp_flags = V4L2_BUF_FLAG_TIMESTAMP_COPY;
2061	dst_vq->lock = &ctx->fdp1->dev_mutex;
2062	dst_vq->dev = ctx->fdp1->dev;
2063
2064	return vb2_queue_init(dst_vq);
2065}
2066
2067/*
2068 * File operations
2069 */
2070static int fdp1_open(struct file *file)
2071{
2072	struct fdp1_dev *fdp1 = video_drvdata(file);
2073	struct v4l2_pix_format_mplane format;
2074	struct fdp1_ctx *ctx = NULL;
2075	struct v4l2_ctrl *ctrl;
2076	int ret = 0;
2077
2078	if (mutex_lock_interruptible(&fdp1->dev_mutex))
2079		return -ERESTARTSYS;
2080
2081	ctx = kzalloc(sizeof(*ctx), GFP_KERNEL);
2082	if (!ctx) {
2083		ret = -ENOMEM;
2084		goto done;
2085	}
2086
2087	v4l2_fh_init(&ctx->fh, video_devdata(file));
2088	ctx->fdp1 = fdp1;
2089
2090	/* Initialise Queues */
2091	INIT_LIST_HEAD(&ctx->fields_queue);
2092
2093	ctx->translen = 1;
2094	ctx->sequence = 0;
2095
2096	/* Initialise controls */
2097
2098	v4l2_ctrl_handler_init(&ctx->hdl, 3);
2099	v4l2_ctrl_new_std_menu_items(&ctx->hdl, &fdp1_ctrl_ops,
2100				     V4L2_CID_DEINTERLACING_MODE,
2101				     FDP1_NEXTFIELD, BIT(0), FDP1_FIXED3D,
2102				     fdp1_ctrl_deint_menu);
2103
2104	ctrl = v4l2_ctrl_new_std(&ctx->hdl, &fdp1_ctrl_ops,
2105				 V4L2_CID_MIN_BUFFERS_FOR_CAPTURE, 1, 2, 1, 1);
2106	if (ctrl)
2107		ctrl->flags |= V4L2_CTRL_FLAG_VOLATILE;
2108
2109	v4l2_ctrl_new_std(&ctx->hdl, &fdp1_ctrl_ops,
2110			  V4L2_CID_ALPHA_COMPONENT, 0, 255, 1, 255);
2111
2112	if (ctx->hdl.error) {
2113		ret = ctx->hdl.error;
2114		goto error_ctx;
2115	}
2116
2117	ctx->fh.ctrl_handler = &ctx->hdl;
2118	v4l2_ctrl_handler_setup(&ctx->hdl);
2119
2120	/* Configure default parameters. */
2121	memset(&format, 0, sizeof(format));
2122	fdp1_set_format(ctx, &format, V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE);
2123
2124	ctx->fh.m2m_ctx = v4l2_m2m_ctx_init(fdp1->m2m_dev, ctx, &queue_init);
2125
2126	if (IS_ERR(ctx->fh.m2m_ctx)) {
2127		ret = PTR_ERR(ctx->fh.m2m_ctx);
2128		goto error_ctx;
2129	}
2130
2131	/* Perform any power management required */
2132	ret = pm_runtime_resume_and_get(fdp1->dev);
2133	if (ret < 0)
2134		goto error_pm;
2135
2136	v4l2_fh_add(&ctx->fh, file);
2137
2138	dprintk(fdp1, "Created instance: %p, m2m_ctx: %p\n",
2139		ctx, ctx->fh.m2m_ctx);
2140
2141	mutex_unlock(&fdp1->dev_mutex);
2142	return 0;
2143
2144error_pm:
2145       v4l2_m2m_ctx_release(ctx->fh.m2m_ctx);
2146error_ctx:
2147	v4l2_ctrl_handler_free(&ctx->hdl);
2148	kfree(ctx);
2149done:
2150	mutex_unlock(&fdp1->dev_mutex);
2151	return ret;
2152}
2153
2154static int fdp1_release(struct file *file)
2155{
2156	struct fdp1_dev *fdp1 = video_drvdata(file);
2157	struct fdp1_ctx *ctx = file_to_ctx(file);
2158
2159	dprintk(fdp1, "Releasing instance %p\n", ctx);
2160
2161	v4l2_fh_del(&ctx->fh, file);
2162	v4l2_fh_exit(&ctx->fh);
2163	v4l2_ctrl_handler_free(&ctx->hdl);
2164	mutex_lock(&fdp1->dev_mutex);
2165	v4l2_m2m_ctx_release(ctx->fh.m2m_ctx);
2166	mutex_unlock(&fdp1->dev_mutex);
2167	kfree(ctx);
2168
2169	pm_runtime_put(fdp1->dev);
2170
2171	return 0;
2172}
2173
2174static const struct v4l2_file_operations fdp1_fops = {
2175	.owner		= THIS_MODULE,
2176	.open		= fdp1_open,
2177	.release	= fdp1_release,
2178	.poll		= v4l2_m2m_fop_poll,
2179	.unlocked_ioctl	= video_ioctl2,
2180	.mmap		= v4l2_m2m_fop_mmap,
2181};
2182
2183static const struct video_device fdp1_videodev = {
2184	.name		= DRIVER_NAME,
2185	.vfl_dir	= VFL_DIR_M2M,
2186	.fops		= &fdp1_fops,
2187	.device_caps	= V4L2_CAP_VIDEO_M2M_MPLANE | V4L2_CAP_STREAMING,
2188	.ioctl_ops	= &fdp1_ioctl_ops,
2189	.minor		= -1,
2190	.release	= video_device_release_empty,
2191};
2192
2193static const struct v4l2_m2m_ops m2m_ops = {
2194	.device_run	= fdp1_m2m_device_run,
2195	.job_ready	= fdp1_m2m_job_ready,
2196	.job_abort	= fdp1_m2m_job_abort,
2197};
2198
2199static irqreturn_t fdp1_irq_handler(int irq, void *dev_id)
2200{
2201	struct fdp1_dev *fdp1 = dev_id;
2202	u32 int_status;
2203	u32 ctl_status;
2204	u32 vint_cnt;
2205	u32 cycles;
2206
2207	int_status = fdp1_read(fdp1, FD1_CTL_IRQSTA);
2208	cycles = fdp1_read(fdp1, FD1_CTL_VCYCLE_STAT);
2209	ctl_status = fdp1_read(fdp1, FD1_CTL_STATUS);
2210	vint_cnt = (ctl_status & FD1_CTL_STATUS_VINT_CNT_MASK) >>
2211			FD1_CTL_STATUS_VINT_CNT_SHIFT;
2212
2213	/* Clear interrupts */
2214	fdp1_write(fdp1, ~(int_status) & FD1_CTL_IRQ_MASK, FD1_CTL_IRQSTA);
2215
2216	if (debug >= 2) {
2217		dprintk(fdp1, "IRQ: 0x%x %s%s%s\n", int_status,
2218			int_status & FD1_CTL_IRQ_VERE ? "[Error]" : "[!E]",
2219			int_status & FD1_CTL_IRQ_VINTE ? "[VSync]" : "[!V]",
2220			int_status & FD1_CTL_IRQ_FREE ? "[FrameEnd]" : "[!F]");
2221
2222		dprintk(fdp1, "CycleStatus = %d (%dms)\n",
2223			cycles, cycles/(fdp1->clk_rate/1000));
2224
2225		dprintk(fdp1,
2226			"Control Status = 0x%08x : VINT_CNT = %d %s:%s:%s:%s\n",
2227			ctl_status, vint_cnt,
2228			ctl_status & FD1_CTL_STATUS_SGREGSET ? "RegSet" : "",
2229			ctl_status & FD1_CTL_STATUS_SGVERR ? "Vsync Error" : "",
2230			ctl_status & FD1_CTL_STATUS_SGFREND ? "FrameEnd" : "",
2231			ctl_status & FD1_CTL_STATUS_BSY ? "Busy" : "");
2232		dprintk(fdp1, "***********************************\n");
2233	}
2234
2235	/* Spurious interrupt */
2236	if (!(FD1_CTL_IRQ_MASK & int_status))
2237		return IRQ_NONE;
2238
2239	/* Work completed, release the frame */
2240	if (FD1_CTL_IRQ_VERE & int_status)
2241		device_frame_end(fdp1, VB2_BUF_STATE_ERROR);
2242	else if (FD1_CTL_IRQ_FREE & int_status)
2243		device_frame_end(fdp1, VB2_BUF_STATE_DONE);
2244
2245	return IRQ_HANDLED;
2246}
2247
2248static int fdp1_probe(struct platform_device *pdev)
2249{
2250	struct fdp1_dev *fdp1;
2251	struct video_device *vfd;
2252	struct device_node *fcp_node;
2253	struct clk *clk;
2254	unsigned int i;
2255
2256	int ret;
2257	int hw_version;
2258
2259	fdp1 = devm_kzalloc(&pdev->dev, sizeof(*fdp1), GFP_KERNEL);
2260	if (!fdp1)
2261		return -ENOMEM;
2262
2263	INIT_LIST_HEAD(&fdp1->free_job_list);
2264	INIT_LIST_HEAD(&fdp1->queued_job_list);
2265	INIT_LIST_HEAD(&fdp1->hw_job_list);
2266
2267	/* Initialise the jobs on the free list */
2268	for (i = 0; i < ARRAY_SIZE(fdp1->jobs); i++)
2269		list_add(&fdp1->jobs[i].list, &fdp1->free_job_list);
2270
2271	mutex_init(&fdp1->dev_mutex);
2272
2273	spin_lock_init(&fdp1->irqlock);
2274	spin_lock_init(&fdp1->device_process_lock);
2275	fdp1->dev = &pdev->dev;
2276	platform_set_drvdata(pdev, fdp1);
2277
2278	/* Memory-mapped registers */
2279	fdp1->regs = devm_platform_ioremap_resource(pdev, 0);
2280	if (IS_ERR(fdp1->regs))
2281		return PTR_ERR(fdp1->regs);
2282
2283	/* Interrupt service routine registration */
2284	ret = platform_get_irq(pdev, 0);
2285	if (ret < 0)
2286		return ret;
2287	fdp1->irq = ret;
2288
2289	ret = devm_request_irq(&pdev->dev, fdp1->irq, fdp1_irq_handler, 0,
2290			       dev_name(&pdev->dev), fdp1);
2291	if (ret) {
2292		dev_err(&pdev->dev, "cannot claim IRQ %d\n", fdp1->irq);
2293		return ret;
2294	}
2295
2296	/* FCP */
2297	fcp_node = of_parse_phandle(pdev->dev.of_node, "renesas,fcp", 0);
2298	if (fcp_node) {
2299		fdp1->fcp = rcar_fcp_get(fcp_node);
2300		of_node_put(fcp_node);
2301		if (IS_ERR(fdp1->fcp)) {
2302			dev_dbg(&pdev->dev, "FCP not found (%pe)\n", fdp1->fcp);
2303			return PTR_ERR(fdp1->fcp);
2304		}
2305	}
2306
2307	/* Determine our clock rate */
2308	clk = clk_get(&pdev->dev, NULL);
2309	if (IS_ERR(clk)) {
2310		ret = PTR_ERR(clk);
2311		goto put_dev;
2312	}
2313
2314	fdp1->clk_rate = clk_get_rate(clk);
2315	clk_put(clk);
2316
2317	/* V4L2 device registration */
2318	ret = v4l2_device_register(&pdev->dev, &fdp1->v4l2_dev);
2319	if (ret) {
2320		v4l2_err(&fdp1->v4l2_dev, "Failed to register video device\n");
2321		goto put_dev;
2322	}
2323
2324	/* M2M registration */
2325	fdp1->m2m_dev = v4l2_m2m_init(&m2m_ops);
2326	if (IS_ERR(fdp1->m2m_dev)) {
2327		v4l2_err(&fdp1->v4l2_dev, "Failed to init mem2mem device\n");
2328		ret = PTR_ERR(fdp1->m2m_dev);
2329		goto unreg_dev;
2330	}
2331
2332	/* Video registration */
2333	fdp1->vfd = fdp1_videodev;
2334	vfd = &fdp1->vfd;
2335	vfd->lock = &fdp1->dev_mutex;
2336	vfd->v4l2_dev = &fdp1->v4l2_dev;
2337	video_set_drvdata(vfd, fdp1);
2338	strscpy(vfd->name, fdp1_videodev.name, sizeof(vfd->name));
2339
2340	ret = video_register_device(vfd, VFL_TYPE_VIDEO, 0);
2341	if (ret) {
2342		v4l2_err(&fdp1->v4l2_dev, "Failed to register video device\n");
2343		goto release_m2m;
2344	}
2345
2346	v4l2_info(&fdp1->v4l2_dev, "Device registered as /dev/video%d\n",
2347		  vfd->num);
2348
2349	/* Power up the cells to read HW */
2350	pm_runtime_enable(&pdev->dev);
2351	ret = pm_runtime_resume_and_get(fdp1->dev);
2352	if (ret < 0)
2353		goto disable_pm;
2354
2355	hw_version = fdp1_read(fdp1, FD1_IP_INTDATA);
2356	switch (hw_version) {
2357	case FD1_IP_GEN2:
2358		dprintk(fdp1, "FDP1 Version R-Car Gen2\n");
2359		break;
2360	case FD1_IP_M3W:
2361		dprintk(fdp1, "FDP1 Version R-Car M3-W\n");
2362		break;
2363	case FD1_IP_H3:
2364		dprintk(fdp1, "FDP1 Version R-Car H3\n");
2365		break;
2366	case FD1_IP_M3N:
2367		dprintk(fdp1, "FDP1 Version R-Car M3-N\n");
2368		break;
2369	case FD1_IP_E3:
2370		dprintk(fdp1, "FDP1 Version R-Car E3\n");
2371		break;
2372	default:
2373		dev_err(fdp1->dev, "FDP1 Unidentifiable (0x%08x)\n",
2374			hw_version);
2375	}
2376
2377	/* Allow the hw to sleep until an open call puts it to use */
2378	pm_runtime_put(fdp1->dev);
2379
2380	return 0;
2381
2382disable_pm:
2383	pm_runtime_disable(fdp1->dev);
2384
2385release_m2m:
2386	v4l2_m2m_release(fdp1->m2m_dev);
2387
2388unreg_dev:
2389	v4l2_device_unregister(&fdp1->v4l2_dev);
2390
2391put_dev:
2392	rcar_fcp_put(fdp1->fcp);
2393	return ret;
2394}
2395
2396static void fdp1_remove(struct platform_device *pdev)
2397{
2398	struct fdp1_dev *fdp1 = platform_get_drvdata(pdev);
2399
2400	v4l2_m2m_release(fdp1->m2m_dev);
2401	video_unregister_device(&fdp1->vfd);
2402	v4l2_device_unregister(&fdp1->v4l2_dev);
2403	pm_runtime_disable(&pdev->dev);
2404	rcar_fcp_put(fdp1->fcp);
2405}
2406
2407static int fdp1_pm_runtime_suspend(struct device *dev)
2408{
2409	struct fdp1_dev *fdp1 = dev_get_drvdata(dev);
2410
2411	rcar_fcp_disable(fdp1->fcp);
2412
2413	return 0;
2414}
2415
2416static int fdp1_pm_runtime_resume(struct device *dev)
2417{
2418	struct fdp1_dev *fdp1 = dev_get_drvdata(dev);
2419
2420	/* Program in the static LUTs */
2421	fdp1_set_lut(fdp1);
2422
2423	return rcar_fcp_enable(fdp1->fcp);
2424}
2425
2426static const struct dev_pm_ops fdp1_pm_ops = {
2427	RUNTIME_PM_OPS(fdp1_pm_runtime_suspend, fdp1_pm_runtime_resume, NULL)
2428};
2429
2430static const struct of_device_id fdp1_dt_ids[] = {
2431	{ .compatible = "renesas,fdp1" },
2432	{ },
2433};
2434MODULE_DEVICE_TABLE(of, fdp1_dt_ids);
2435
2436static struct platform_driver fdp1_pdrv = {
2437	.probe		= fdp1_probe,
2438	.remove		= fdp1_remove,
2439	.driver		= {
2440		.name	= DRIVER_NAME,
2441		.of_match_table = fdp1_dt_ids,
2442		.pm	= pm_ptr(&fdp1_pm_ops),
2443	},
2444};
2445
2446module_platform_driver(fdp1_pdrv);
2447
2448MODULE_DESCRIPTION("Renesas R-Car Fine Display Processor Driver");
2449MODULE_AUTHOR("Kieran Bingham <kieran@bingham.xyz>");
2450MODULE_LICENSE("GPL");
2451MODULE_ALIAS("platform:" DRIVER_NAME);
~/ Read-only file preview.