// SPDX-License-Identifier: GPL-2.0+
/*
* V4L2 Capture IC Preprocess Subdev for Freescale i.MX5/6 SOC
*
* This subdevice handles capture of video frames from the CSI or VDIC,
* which are routed directly to the Image Converter preprocess tasks,
* for resizing, colorspace conversion, and rotation.
*
* Copyright (c) 2012-2017 Mentor Graphics Inc.
*/
#include <linux/delay.h>
#include <linux/interrupt.h>
#include <linux/module.h>
#include <linux/sched.h>
#include <linux/slab.h>
#include <linux/spinlock.h>
#include <linux/timer.h>
#include <media/v4l2-ctrls.h>
#include <media/v4l2-device.h>
#include <media/v4l2-ioctl.h>
#include <media/v4l2-mc.h>
#include <media/v4l2-subdev.h>
#include <media/imx.h>
#include "imx-media.h"
#include "imx-ic.h"
/*
* Min/Max supported width and heights.
*
* We allow planar output, so we have to align width at the source pad
* by 16 pixels to meet IDMAC alignment requirements for possible planar
* output.
*
* TODO: move this into pad format negotiation, if capture device
* has not requested a planar format, we should allow 8 pixel
* alignment at the source pad.
*/
#define MIN_W_SINK 176
#define MIN_H_SINK 144
#define MAX_W_SINK 4096
#define MAX_H_SINK 4096
#define W_ALIGN_SINK 3 /* multiple of 8 pixels */
#define H_ALIGN_SINK 1 /* multiple of 2 lines */
#define MAX_W_SRC 1024
#define MAX_H_SRC 1024
#define W_ALIGN_SRC 1 /* multiple of 2 pixels */
#define H_ALIGN_SRC 1 /* multiple of 2 lines */
#define S_ALIGN 1 /* multiple of 2 */
struct prp_priv {
struct imx_ic_priv *ic_priv;
struct media_pad pad[PRPENCVF_NUM_PADS];
/* the video device at output pad */
struct imx_media_video_dev *vdev;
/* lock to protect all members below */
struct mutex lock;
/* IPU units we require */
struct ipu_ic *ic;
struct ipuv3_channel *out_ch;
struct ipuv3_channel *rot_in_ch;
struct ipuv3_channel *rot_out_ch;
/* active vb2 buffers to send to video dev sink */
struct imx_media_buffer *active_vb2_buf[2];
struct imx_media_dma_buf underrun_buf;
int ipu_buf_num; /* ipu double buffer index: 0-1 */
/* the sink for the captured frames */
struct media_entity *sink;
/* the source subdev */
struct v4l2_subdev *src_sd;
struct v4l2_mbus_framefmt format_mbus[PRPENCVF_NUM_PADS];
const struct imx_media_pixfmt *cc[PRPENCVF_NUM_PADS];
struct v4l2_fract frame_interval;
struct imx_media_dma_buf rot_buf[2];
/* controls */
struct v4l2_ctrl_handler ctrl_hdlr;
int rotation; /* degrees */
bool hflip;
bool vflip;
/* derived from rotation, hflip, vflip controls */