linux/drivers/media/platform/ti/vpe/vpe.c

// SPDX-License-Identifier: GPL-2.0-only
/*
 * TI VPE mem2mem driver, based on the virtual v4l2-mem2mem example driver
 *
 * Copyright (c) 2013 Texas Instruments Inc.
 * David Griego, <[email protected]>
 * Dale Farnsworth, <[email protected]>
 * Archit Taneja, <[email protected]>
 *
 * Copyright (c) 2009-2010 Samsung Electronics Co., Ltd.
 * Pawel Osciak, <[email protected]>
 * Marek Szyprowski, <[email protected]>
 *
 * Based on the virtual v4l2-mem2mem example device
 */

#include <linux/delay.h>
#include <linux/dma-mapping.h>
#include <linux/err.h>
#include <linux/fs.h>
#include <linux/interrupt.h>
#include <linux/io.h>
#include <linux/ioctl.h>
#include <linux/module.h>
#include <linux/of.h>
#include <linux/platform_device.h>
#include <linux/pm_runtime.h>
#include <linux/sched.h>
#include <linux/slab.h>
#include <linux/videodev2.h>
#include <linux/log2.h>
#include <linux/sizes.h>

#include <media/v4l2-common.h>
#include <media/v4l2-ctrls.h>
#include <media/v4l2-device.h>
#include <media/v4l2-event.h>
#include <media/v4l2-ioctl.h>
#include <media/v4l2-mem2mem.h>
#include <media/videobuf2-v4l2.h>
#include <media/videobuf2-dma-contig.h>

#include "vpdma.h"
#include "vpdma_priv.h"
#include "vpe_regs.h"
#include "sc.h"
#include "csc.h"

#define VPE_MODULE_NAME

/* minimum and maximum frame sizes */
#define MIN_W
#define MIN_H
#define MAX_W
#define MAX_H

/* required alignments */
#define S_ALIGN
#define H_ALIGN

/* flags that indicate a format can be used for capture/output */
#define VPE_FMT_TYPE_CAPTURE
#define VPE_FMT_TYPE_OUTPUT

/* used as plane indices */
#define VPE_MAX_PLANES
#define VPE_LUMA
#define VPE_CHROMA

/* per m2m context info */
#define VPE_MAX_SRC_BUFS

#define VPE_DEF_BUFS_PER_JOB

/*
 * each VPE context can need up to 3 config descriptors, 7 input descriptors,
 * 3 output descriptors, and 10 control descriptors
 */
#define VPE_DESC_LIST_SIZE

#define vpe_dbg(vpedev, fmt, arg...)
#define vpe_err(vpedev, fmt, arg...)

struct vpe_us_coeffs {};

/*
 * Default upsampler coefficients
 */
static const struct vpe_us_coeffs us_coeffs[] =;

/*
 * the following registers are for configuring some of the parameters of the
 * motion and edge detection blocks inside DEI, these generally remain the same,
 * these could be passed later via userspace if some one needs to tweak these.
 */
struct vpe_dei_regs {};

/*
 * default expert DEI register values, unlikely to be modified.
 */
static const struct vpe_dei_regs dei_regs =;

/*
 * The port_data structure contains per-port data.
 */
struct vpe_port_data {};

/*
 * Define indices into the port_data tables
 */
#define VPE_PORT_LUMA1_IN
#define VPE_PORT_CHROMA1_IN
#define VPE_PORT_LUMA2_IN
#define VPE_PORT_CHROMA2_IN
#define VPE_PORT_LUMA3_IN
#define VPE_PORT_CHROMA3_IN
#define VPE_PORT_MV_IN
#define VPE_PORT_MV_OUT
#define VPE_PORT_LUMA_OUT
#define VPE_PORT_CHROMA_OUT
#define VPE_PORT_RGB_OUT

static const struct vpe_port_data port_data[11] =;


/* driver info for each of the supported video formats */
struct vpe_fmt {};

static struct vpe_fmt vpe_formats[] =;

/*
 * per-queue, driver-specific private data.
 * there is one source queue and one destination queue for each m2m context.
 */
struct vpe_q_data {};

/* vpe_q_data flag bits */
#define Q_DATA_FRAME_1D
#define Q_DATA_MODE_TILED
#define Q_DATA_INTERLACED_ALTERNATE
#define Q_DATA_INTERLACED_SEQ_TB
#define Q_DATA_INTERLACED_SEQ_BT

#define Q_IS_SEQ_XX

#define Q_IS_INTERLACED

enum {};

/* find our format description corresponding to the passed v4l2_format */
static struct vpe_fmt *__find_format(u32 fourcc)
{}

static struct vpe_fmt *find_format(struct v4l2_format *f)
{}

/*
 * there is one vpe_dev structure in the driver, it is shared by
 * all instances.
 */
struct vpe_dev {};

/*
 * There is one vpe_ctx structure for each m2m context.
 */
struct vpe_ctx {};


/*
 * M2M devices get 2 queues.
 * Return the queue given the type.
 */
static struct vpe_q_data *get_q_data(struct vpe_ctx *ctx,
				     enum v4l2_buf_type type)
{}

static u32 read_reg(struct vpe_dev *dev, int offset)
{}

static void write_reg(struct vpe_dev *dev, int offset, u32 value)
{}

/* register field read/write helpers */
static int get_field(u32 value, u32 mask, int shift)
{}

static int read_field_reg(struct vpe_dev *dev, int offset, u32 mask, int shift)
{}

static void write_field(u32 *valp, u32 field, u32 mask, int shift)
{}

static void write_field_reg(struct vpe_dev *dev, int offset, u32 field,
		u32 mask, int shift)
{}

/*
 * DMA address/data block for the shadow registers
 */
struct vpe_mmr_adb {};

#define GET_OFFSET_TOP(ctx, obj, reg)

#define VPE_SET_MMR_ADB_HDR(ctx, hdr, regs, offset_a)
/*
 * Set the headers for all of the address/data block structures.
 */
static void init_adb_hdrs(struct vpe_ctx *ctx)
{
	VPE_SET_MMR_ADB_HDR(ctx, out_fmt_hdr, out_fmt_reg, VPE_CLK_FORMAT_SELECT);
	VPE_SET_MMR_ADB_HDR(ctx, us1_hdr, us1_regs, VPE_US1_R0);
	VPE_SET_MMR_ADB_HDR(ctx, us2_hdr, us2_regs, VPE_US2_R0);
	VPE_SET_MMR_ADB_HDR(ctx, us3_hdr, us3_regs, VPE_US3_R0);
	VPE_SET_MMR_ADB_HDR(ctx, dei_hdr, dei_regs, VPE_DEI_FRAME_SIZE);
	VPE_SET_MMR_ADB_HDR(ctx, sc_hdr0, sc_regs0,
		GET_OFFSET_TOP(ctx, ctx->dev->sc, CFG_SC0));
	VPE_SET_MMR_ADB_HDR(ctx, sc_hdr8, sc_regs8,
		GET_OFFSET_TOP(ctx, ctx->dev->sc, CFG_SC8));
	VPE_SET_MMR_ADB_HDR(ctx, sc_hdr17, sc_regs17,
		GET_OFFSET_TOP(ctx, ctx->dev->sc, CFG_SC17));
	VPE_SET_MMR_ADB_HDR(ctx, csc_hdr, csc_regs,
		GET_OFFSET_TOP(ctx, ctx->dev->csc, CSC_CSC00));
};

/*
 * Allocate or re-allocate the motion vector DMA buffers
 * There are two buffers, one for input and one for output.
 * However, the roles are reversed after each field is processed.
 * In other words, after each field is processed, the previous
 * output (dst) MV buffer becomes the new input (src) MV buffer.
 */
static int realloc_mv_buffers(struct vpe_ctx *ctx, size_t size)
{}

static void free_mv_buffers(struct vpe_ctx *ctx)
{}

/*
 * While de-interlacing, we keep the two most recent input buffers
 * around.  This function frees those two buffers when we have
 * finished processing the current stream.
 */
static void free_vbs(struct vpe_ctx *ctx)
{}

/*
 * Enable or disable the VPE clocks
 */
static void vpe_set_clock_enable(struct vpe_dev *dev, bool on)
{}

static void vpe_top_reset(struct vpe_dev *dev)
{}

static void vpe_top_vpdma_reset(struct vpe_dev *dev)
{}

/*
 * Load the correct of upsampler coefficients into the shadow MMRs
 */
static void set_us_coefficients(struct vpe_ctx *ctx)
{}

/*
 * Set the upsampler config mode and the VPDMA line mode in the shadow MMRs.
 */
static void set_cfg_modes(struct vpe_ctx *ctx)
{}

static void set_line_modes(struct vpe_ctx *ctx)
{}

/*
 * Set the shadow registers that are modified when the source
 * format changes.
 */
static void set_src_registers(struct vpe_ctx *ctx)
{}

/*
 * Set the shadow registers that are modified when the destination
 * format changes.
 */
static void set_dst_registers(struct vpe_ctx *ctx)
{}

/*
 * Set the de-interlacer shadow register values
 */
static void set_dei_regs(struct vpe_ctx *ctx)
{}

static void set_dei_shadow_registers(struct vpe_ctx *ctx)
{}

static void config_edi_input_mode(struct vpe_ctx *ctx, int mode)
{}

/*
 * Set the shadow registers whose values are modified when either the
 * source or destination format is changed.
 */
static int set_srcdst_params(struct vpe_ctx *ctx)
{}

/*
 * mem2mem callbacks
 */

/*
 * job_ready() - check whether an instance is ready to be scheduled to run
 */
static int job_ready(void *priv)
{}

static void job_abort(void *priv)
{}

static void vpe_dump_regs(struct vpe_dev *dev)
{}

static void add_out_dtd(struct vpe_ctx *ctx, int port)
{}

static void add_in_dtd(struct vpe_ctx *ctx, int port)
{}

/*
 * Enable the expected IRQ sources
 */
static void enable_irqs(struct vpe_ctx *ctx)
{}

static void disable_irqs(struct vpe_ctx *ctx)
{}

/* device_run() - prepares and starts the device
 *
 * This function is only called when both the source and destination
 * buffers are in place.
 */
static void device_run(void *priv)
{}

static void dei_error(struct vpe_ctx *ctx)
{}

static void ds1_uv_error(struct vpe_ctx *ctx)
{}

static irqreturn_t vpe_irq(int irq_vpe, void *data)
{}

/*
 * video ioctls
 */
static int vpe_querycap(struct file *file, void *priv,
			struct v4l2_capability *cap)
{}

static int __enum_fmt(struct v4l2_fmtdesc *f, u32 type)
{}

static int vpe_enum_fmt(struct file *file, void *priv,
				struct v4l2_fmtdesc *f)
{}

static int vpe_g_fmt(struct file *file, void *priv, struct v4l2_format *f)
{}

static int __vpe_try_fmt(struct vpe_ctx *ctx, struct v4l2_format *f,
		       struct vpe_fmt *fmt, int type)
{}

static int vpe_try_fmt(struct file *file, void *priv, struct v4l2_format *f)
{}

static int __vpe_s_fmt(struct vpe_ctx *ctx, struct v4l2_format *f)
{}

static int vpe_s_fmt(struct file *file, void *priv, struct v4l2_format *f)
{}

static int __vpe_try_selection(struct vpe_ctx *ctx, struct v4l2_selection *s)
{}

static int vpe_g_selection(struct file *file, void *fh,
		struct v4l2_selection *s)
{}


static int vpe_s_selection(struct file *file, void *fh,
		struct v4l2_selection *s)
{}

/*
 * defines number of buffers/frames a context can process with VPE before
 * switching to a different context. default value is 1 buffer per context
 */
#define V4L2_CID_VPE_BUFS_PER_JOB

static int vpe_s_ctrl(struct v4l2_ctrl *ctrl)
{}

static const struct v4l2_ctrl_ops vpe_ctrl_ops =;

static const struct v4l2_ioctl_ops vpe_ioctl_ops =;

/*
 * Queue operations
 */
static int vpe_queue_setup(struct vb2_queue *vq,
			   unsigned int *nbuffers, unsigned int *nplanes,
			   unsigned int sizes[], struct device *alloc_devs[])
{}

static int vpe_buf_prepare(struct vb2_buffer *vb)
{}

static void vpe_buf_queue(struct vb2_buffer *vb)
{}

static int check_srcdst_sizes(struct vpe_ctx *ctx)
{}

static void vpe_return_all_buffers(struct vpe_ctx *ctx,  struct vb2_queue *q,
				   enum vb2_buffer_state state)
{}

static int vpe_start_streaming(struct vb2_queue *q, unsigned int count)
{}

static void vpe_stop_streaming(struct vb2_queue *q)
{}

static const struct vb2_ops vpe_qops =;

static int queue_init(void *priv, struct vb2_queue *src_vq,
		      struct vb2_queue *dst_vq)
{}

static const struct v4l2_ctrl_config vpe_bufs_per_job =;

/*
 * File operations
 */
static int vpe_open(struct file *file)
{}

static int vpe_release(struct file *file)
{}

static const struct v4l2_file_operations vpe_fops =;

static const struct video_device vpe_videodev =;

static const struct v4l2_m2m_ops m2m_ops =;

static int vpe_runtime_get(struct platform_device *pdev)
{}

static void vpe_runtime_put(struct platform_device *pdev)
{}

static void vpe_fw_cb(struct platform_device *pdev)
{}

static int vpe_probe(struct platform_device *pdev)
{}

static void vpe_remove(struct platform_device *pdev)
{}

#if defined(CONFIG_OF)
static const struct of_device_id vpe_of_match[] =;
MODULE_DEVICE_TABLE(of, vpe_of_match);
#endif

static struct platform_driver vpe_pdrv =;

module_platform_driver();

MODULE_DESCRIPTION();
MODULE_AUTHOR();
MODULE_LICENSE();