linux/drivers/media/platform/renesas/rcar_jpu.c

// SPDX-License-Identifier: GPL-2.0
/*
 * Author: Mikhail Ulyanov
 * Copyright (C) 2014-2015 Cogent Embedded, Inc.  <[email protected]>
 * Copyright (C) 2014-2015 Renesas Electronics Corporation
 *
 * This is based on the drivers/media/platform/samsung/s5p-jpeg driver by
 * Andrzej Pietrasiewicz and Jacek Anaszewski.
 * Some portions of code inspired by VSP1 driver by Laurent Pinchart.
 *
 * TODO in order of priority:
 *      1) Rotation
 *      2) Cropping
 *      3) V4L2_CID_JPEG_ACTIVE_MARKER
 */

#include <linux/unaligned.h>
#include <linux/clk.h>
#include <linux/err.h>
#include <linux/interrupt.h>
#include <linux/io.h>
#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/of.h>
#include <linux/platform_device.h>
#include <linux/slab.h>
#include <linux/spinlock.h>
#include <linux/string.h>
#include <linux/videodev2.h>
#include <media/jpeg.h>
#include <media/v4l2-ctrls.h>
#include <media/v4l2-device.h>
#include <media/v4l2-event.h>
#include <media/v4l2-fh.h>
#include <media/v4l2-mem2mem.h>
#include <media/v4l2-ioctl.h>
#include <media/videobuf2-v4l2.h>
#include <media/videobuf2-dma-contig.h>


#define DRV_NAME

/*
 * Align JPEG header end to cache line to make sure we will not have any issues
 * with cache; additionally to requirement (33.3.27 R01UH0501EJ0100 Rev.1.00)
 */
#define JPU_JPEG_HDR_SIZE
#define JPU_JPEG_MAX_BYTES_PER_PIXEL
#define JPU_JPEG_MIN_SIZE
#define JPU_JPEG_QTBL_SIZE
#define JPU_JPEG_HDCTBL_SIZE
#define JPU_JPEG_HACTBL_SIZE
#define JPU_JPEG_HEIGHT_OFFSET
#define JPU_JPEG_WIDTH_OFFSET
#define JPU_JPEG_SUBS_OFFSET
#define JPU_JPEG_QTBL_LUM_OFFSET
#define JPU_JPEG_QTBL_CHR_OFFSET
#define JPU_JPEG_HDCTBL_LUM_OFFSET
#define JPU_JPEG_HACTBL_LUM_OFFSET
#define JPU_JPEG_HDCTBL_CHR_OFFSET
#define JPU_JPEG_HACTBL_CHR_OFFSET
#define JPU_JPEG_PADDING_OFFSET
#define JPU_JPEG_LUM
#define JPU_JPEG_CHR
#define JPU_JPEG_DC
#define JPU_JPEG_AC

#define JPU_JPEG_422
#define JPU_JPEG_420

#define JPU_JPEG_DEFAULT_422_PIX_FMT
#define JPU_JPEG_DEFAULT_420_PIX_FMT

#define JPU_RESET_TIMEOUT
#define JPU_JOB_TIMEOUT
#define JPU_MAX_QUALITY
#define JPU_WIDTH_MIN
#define JPU_HEIGHT_MIN
#define JPU_WIDTH_MAX
#define JPU_HEIGHT_MAX
#define JPU_MEMALIGN

/* Flags that indicate a format can be used for capture/output */
#define JPU_FMT_TYPE_OUTPUT
#define JPU_FMT_TYPE_CAPTURE
#define JPU_ENC_CAPTURE
#define JPU_ENC_OUTPUT
#define JPU_DEC_CAPTURE
#define JPU_DEC_OUTPUT

/*
 * JPEG registers and bits
 */

/* JPEG code mode register */
#define JCMOD
#define JCMOD_PCTR
#define JCMOD_MSKIP_ENABLE
#define JCMOD_DSP_ENC
#define JCMOD_DSP_DEC
#define JCMOD_REDU
#define JCMOD_REDU_422
#define JCMOD_REDU_420

/* JPEG code command register */
#define JCCMD
#define JCCMD_SRST
#define JCCMD_JEND
#define JCCMD_JSRT

/* JPEG code quantization table number register */
#define JCQTN
#define JCQTN_SHIFT(t)

/* JPEG code Huffman table number register */
#define JCHTN
#define JCHTN_AC_SHIFT(t)
#define JCHTN_DC_SHIFT(t)

#define JCVSZU
#define JCVSZD
#define JCHSZU
#define JCHSZD
#define JCSZ_MASK

#define JCDTCU
#define JCDTCM
#define JCDTCD

/* JPEG interrupt enable register */
#define JINTE
#define JINTE_ERR
#define JINTE_TRANSF_COMPL

/* JPEG interrupt status register */
#define JINTS
#define JINTS_MASK
#define JINTS_ERR
#define JINTS_PROCESS_COMPL
#define JINTS_TRANSF_COMPL

#define JCDERR
#define JCDERR_MASK

/* JPEG interface encoding */
#define JIFECNT
#define JIFECNT_INFT_422
#define JIFECNT_INFT_420
#define JIFECNT_SWAP_WB

#define JIFESYA1
#define JIFESCA1
#define JIFESYA2
#define JIFESCA2
#define JIFESMW
#define JIFESVSZ
#define JIFESHSZ
#define JIFEDA1
#define JIFEDA2

/* JPEG decoding control register */
#define JIFDCNT
#define JIFDCNT_SWAP_WB

#define JIFDSA1
#define JIFDDMW
#define JIFDDVSZ
#define JIFDDHSZ
#define JIFDDYA1
#define JIFDDCA1

#define JCQTBL(n)
#define JCHTBD(n)
#define JCHTBA(n)

/**
 * struct jpu - JPEG IP abstraction
 * @mutex: the mutex protecting this structure
 * @lock: spinlock protecting the device contexts
 * @v4l2_dev: v4l2 device for mem2mem mode
 * @vfd_encoder: video device node for encoder mem2mem mode
 * @vfd_decoder: video device node for decoder mem2mem mode
 * @m2m_dev: v4l2 mem2mem device data
 * @curr: pointer to current context
 * @regs: JPEG IP registers mapping
 * @irq: JPEG IP irq
 * @clk: JPEG IP clock
 * @dev: JPEG IP struct device
 * @ref_count: reference counter
 */
struct jpu {};

/**
 * struct jpu_buffer - driver's specific video buffer
 * @buf: m2m buffer
 * @compr_quality: destination image quality in compression mode
 * @subsampling: source image subsampling in decompression mode
 */
struct jpu_buffer {};

/**
 * struct jpu_fmt - driver's internal format data
 * @fourcc: the fourcc code, 0 if not applicable
 * @colorspace: the colorspace specifier
 * @bpp: number of bits per pixel per plane
 * @h_align: horizontal alignment order (align to 2^h_align)
 * @v_align: vertical alignment order (align to 2^v_align)
 * @subsampling: (horizontal:4 | vertical:4) subsampling factor
 * @num_planes: number of planes
 * @types: types of queue this format is applicable to
 */
struct jpu_fmt {};

/**
 * struct jpu_q_data - parameters of one queue
 * @fmtinfo: driver-specific format of this queue
 * @format: multiplanar format of this queue
 * @sequence: sequence number
 */
struct jpu_q_data {};

/**
 * struct jpu_ctx - the device context data
 * @jpu: JPEG IP device for this context
 * @encoder: compression (encode) operation or decompression (decode)
 * @compr_quality: destination image quality in compression (encode) mode
 * @out_q: source (output) queue information
 * @cap_q: destination (capture) queue information
 * @fh: file handler
 * @ctrl_handler: controls handler
 */
struct jpu_ctx {};

 /**
 * jpeg_buffer - description of memory containing input JPEG data
 * @end: end position in the buffer
 * @curr: current position in the buffer
 */
struct jpeg_buffer {};

static struct jpu_fmt jpu_formats[] =;

static const u8 zigzag[] =;

#define QTBL_SIZE
#define HDCTBL_SIZE
#define HACTBL_SIZE
/*
 * Start of image; Quantization tables
 * SOF0 (17 bytes payload) is Baseline DCT - Sample precision, height, width,
 * Number of image components, (Ci:8 - Hi:4 - Vi:4 - Tq:8) * 3 - Y,Cb,Cr;
 * Huffman tables; Padding with 0xff (33.3.27 R01UH0501EJ0100 Rev.1.00)
 */
#define JPU_JPEG_HDR_BLOB

static unsigned char jpeg_hdrs[JPU_MAX_QUALITY][JPU_JPEG_HDR_SIZE] =;

static const unsigned int qtbl_lum[JPU_MAX_QUALITY][QTBL_SIZE] =;

static const unsigned int qtbl_chr[JPU_MAX_QUALITY][QTBL_SIZE] =;

static const unsigned int hdctbl_lum[HDCTBL_SIZE] =;

static const unsigned int hdctbl_chr[HDCTBL_SIZE] =;

static const unsigned int hactbl_lum[HACTBL_SIZE] =;

static const unsigned int hactbl_chr[HACTBL_SIZE] =;

static const char *error_to_text[16] =;

static struct jpu_buffer *vb2_to_jpu_buffer(struct vb2_v4l2_buffer *vb)
{}

static u32 jpu_read(struct jpu *jpu, unsigned int reg)
{}

static void jpu_write(struct jpu *jpu, u32 val, unsigned int reg)
{}

static struct jpu_ctx *ctrl_to_ctx(struct v4l2_ctrl *c)
{}

static struct jpu_ctx *fh_to_ctx(struct v4l2_fh *fh)
{}

static void jpu_set_tbl(struct jpu *jpu, u32 reg, const unsigned int *tbl,
			unsigned int len) {}

static void jpu_set_qtbl(struct jpu *jpu, unsigned short quality)
{}

static void jpu_set_htbl(struct jpu *jpu)
{}

static int jpu_wait_reset(struct jpu *jpu)
{}

static int jpu_reset(struct jpu *jpu)
{}

/*
 * ============================================================================
 * video ioctl operations
 * ============================================================================
 */
static void put_qtbl(u8 *p, const u8 *qtbl)
{}

static void put_htbl(u8 *p, const u8 *htbl, unsigned int len)
{}

static void jpu_generate_hdr(unsigned short quality, unsigned char *p)
{}

static int get_byte(struct jpeg_buffer *buf)
{}

static int get_word_be(struct jpeg_buffer *buf, unsigned int *word)
{}

static void skip(struct jpeg_buffer *buf, unsigned long len)
{}

static u8 jpu_parse_hdr(void *buffer, unsigned long size, unsigned int *width,
			  unsigned int *height)
{}

static int jpu_querycap(struct file *file, void *priv,
			struct v4l2_capability *cap)
{}

static struct jpu_fmt *jpu_find_format(bool encoder, u32 pixelformat,
				       unsigned int fmt_type)
{}

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

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

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

static struct jpu_q_data *jpu_get_q_data(struct jpu_ctx *ctx,
					 enum v4l2_buf_type type)
{}

static void jpu_bound_align_image(u32 *w, unsigned int w_min,
				  unsigned int w_max, unsigned int w_align,
				  u32 *h, unsigned int h_min,
				  unsigned int h_max, unsigned int h_align)
{}

static int __jpu_try_fmt(struct jpu_ctx *ctx, struct jpu_fmt **fmtinfo,
			 struct v4l2_pix_format_mplane *pix,
			 enum v4l2_buf_type type)
{}

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

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

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

/*
 * V4L2 controls
 */
static int jpu_s_ctrl(struct v4l2_ctrl *ctrl)
{}

static const struct v4l2_ctrl_ops jpu_ctrl_ops =;

static int jpu_streamon(struct file *file, void *priv, enum v4l2_buf_type type)
{}

static const struct v4l2_ioctl_ops jpu_ioctl_ops =;

static int jpu_controls_create(struct jpu_ctx *ctx)
{}

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

static int jpu_buf_prepare(struct vb2_buffer *vb)
{}

static void jpu_buf_queue(struct vb2_buffer *vb)
{}

static void jpu_buf_finish(struct vb2_buffer *vb)
{}

static int jpu_start_streaming(struct vb2_queue *vq, unsigned count)
{}

static void jpu_stop_streaming(struct vb2_queue *vq)
{}

static const struct vb2_ops jpu_qops =;

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

/*
 * ============================================================================
 * Device file operations
 * ============================================================================
 */
static int jpu_open(struct file *file)
{}

static int jpu_release(struct file *file)
{}

static const struct v4l2_file_operations jpu_fops =;

/*
 * ============================================================================
 * mem2mem callbacks
 * ============================================================================
 */
static void jpu_cleanup(struct jpu_ctx *ctx, bool reset)
{}

static void jpu_device_run(void *priv)
{}

static const struct v4l2_m2m_ops jpu_m2m_ops =;

/*
 * ============================================================================
 * IRQ handler
 * ============================================================================
 */
static irqreturn_t jpu_irq_handler(int irq, void *dev_id)
{}

/*
 * ============================================================================
 * Driver basic infrastructure
 * ============================================================================
 */
static const struct of_device_id jpu_dt_ids[] =;
MODULE_DEVICE_TABLE(of, jpu_dt_ids);

static int jpu_probe(struct platform_device *pdev)
{}

static void jpu_remove(struct platform_device *pdev)
{}

#ifdef CONFIG_PM_SLEEP
static int jpu_suspend(struct device *dev)
{}

static int jpu_resume(struct device *dev)
{}
#endif

static const struct dev_pm_ops jpu_pm_ops =;

static struct platform_driver jpu_driver =;

module_platform_driver();

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