linux/drivers/media/platform/aspeed/aspeed-video.c

// SPDX-License-Identifier: GPL-2.0-or-later
// Copyright 2020 IBM Corp.
// Copyright (c) 2019-2020 Intel Corporation

#include <linux/atomic.h>
#include <linux/bitfield.h>
#include <linux/clk.h>
#include <linux/delay.h>
#include <linux/device.h>
#include <linux/dma-mapping.h>
#include <linux/interrupt.h>
#include <linux/jiffies.h>
#include <linux/module.h>
#include <linux/mutex.h>
#include <linux/of.h>
#include <linux/of_irq.h>
#include <linux/of_reserved_mem.h>
#include <linux/platform_device.h>
#include <linux/sched.h>
#include <linux/spinlock.h>
#include <linux/string.h>
#include <linux/v4l2-controls.h>
#include <linux/videodev2.h>
#include <linux/wait.h>
#include <linux/workqueue.h>
#include <linux/debugfs.h>
#include <linux/ktime.h>
#include <media/v4l2-ctrls.h>
#include <media/v4l2-dev.h>
#include <media/v4l2-device.h>
#include <media/v4l2-dv-timings.h>
#include <media/v4l2-event.h>
#include <media/v4l2-ioctl.h>
#include <media/videobuf2-dma-contig.h>
#include <uapi/linux/aspeed-video.h>

#define ASPEED_VIDEO_V4L2_MIN_BUF_REQ

#define DEVICE_NAME

#define ASPEED_VIDEO_JPEG_NUM_QUALITIES
#define ASPEED_VIDEO_JPEG_HEADER_SIZE
#define ASPEED_VIDEO_JPEG_QUANT_SIZE
#define ASPEED_VIDEO_JPEG_DCT_SIZE

#define MAX_FRAME_RATE
#define MAX_HEIGHT
#define MAX_WIDTH
#define MIN_HEIGHT
#define MIN_WIDTH

#define NUM_POLARITY_CHECKS
#define INVALID_RESOLUTION_RETRIES
#define INVALID_RESOLUTION_DELAY
#define RESOLUTION_CHANGE_DELAY
#define MODE_DETECT_TIMEOUT
#define STOP_TIMEOUT
#define DIRECT_FETCH_THRESHOLD

#define VE_MAX_SRC_BUFFER_SIZE
#define VE_JPEG_HEADER_SIZE
#define VE_BCD_BUFF_SIZE

#define VE_PROTECTION_KEY
#define VE_PROTECTION_KEY_UNLOCK

#define VE_SEQ_CTRL
#define VE_SEQ_CTRL_TRIG_MODE_DET
#define VE_SEQ_CTRL_TRIG_CAPTURE
#define VE_SEQ_CTRL_FORCE_IDLE
#define VE_SEQ_CTRL_MULT_FRAME
#define VE_SEQ_CTRL_TRIG_COMP
#define VE_SEQ_CTRL_AUTO_COMP
#define VE_SEQ_CTRL_EN_WATCHDOG
#define VE_SEQ_CTRL_YUV420
#define VE_SEQ_CTRL_COMP_FMT
#define VE_SEQ_CTRL_HALT
#define VE_SEQ_CTRL_EN_WATCHDOG_COMP
#define VE_SEQ_CTRL_TRIG_JPG
#define VE_SEQ_CTRL_CAP_BUSY
#define VE_SEQ_CTRL_COMP_BUSY

#define AST2500_VE_SEQ_CTRL_JPEG_MODE
#define AST2400_VE_SEQ_CTRL_JPEG_MODE

#define VE_CTRL
#define VE_CTRL_HSYNC_POL
#define VE_CTRL_VSYNC_POL
#define VE_CTRL_SOURCE
#define VE_CTRL_INT_DE
#define VE_CTRL_DIRECT_FETCH
#define VE_CTRL_CAPTURE_FMT
#define VE_CTRL_AUTO_OR_CURSOR
#define VE_CTRL_CLK_INVERSE
#define VE_CTRL_CLK_DELAY
#define VE_CTRL_INTERLACE
#define VE_CTRL_HSYNC_POL_CTRL
#define VE_CTRL_FRC

#define VE_TGS_0
#define VE_TGS_1
#define VE_TGS_FIRST
#define VE_TGS_LAST

#define VE_SCALING_FACTOR
#define VE_SCALING_FILTER0
#define VE_SCALING_FILTER1
#define VE_SCALING_FILTER2
#define VE_SCALING_FILTER3

#define VE_BCD_CTRL
#define VE_BCD_CTRL_EN_BCD
#define VE_BCD_CTRL_EN_ABCD
#define VE_BCD_CTRL_EN_CB
#define VE_BCD_CTRL_THR
#define VE_BCD_CTRL_ABCD_THR

#define VE_CAP_WINDOW
#define VE_COMP_WINDOW
#define VE_COMP_PROC_OFFSET
#define VE_COMP_OFFSET
#define VE_JPEG_ADDR
#define VE_SRC0_ADDR
#define VE_SRC_SCANLINE_OFFSET
#define VE_SRC1_ADDR
#define VE_BCD_ADDR
#define VE_COMP_ADDR

#define VE_STREAM_BUF_SIZE
#define VE_STREAM_BUF_SIZE_N_PACKETS
#define VE_STREAM_BUF_SIZE_P_SIZE

#define VE_COMP_CTRL
#define VE_COMP_CTRL_VQ_DCT_ONLY
#define VE_COMP_CTRL_VQ_4COLOR
#define VE_COMP_CTRL_QUANTIZE
#define VE_COMP_CTRL_EN_BQ
#define VE_COMP_CTRL_EN_CRYPTO
#define VE_COMP_CTRL_DCT_CHR
#define VE_COMP_CTRL_DCT_LUM
#define VE_COMP_CTRL_EN_HQ
#define VE_COMP_CTRL_RSVD
#define VE_COMP_CTRL_ENCODE
#define VE_COMP_CTRL_HQ_DCT_CHR
#define VE_COMP_CTRL_HQ_DCT_LUM

#define VE_CB_ADDR

#define AST2400_VE_COMP_SIZE_READ_BACK
#define AST2600_VE_COMP_SIZE_READ_BACK

#define VE_SRC_LR_EDGE_DET
#define VE_SRC_LR_EDGE_DET_LEFT
#define VE_SRC_LR_EDGE_DET_NO_V
#define VE_SRC_LR_EDGE_DET_NO_H
#define VE_SRC_LR_EDGE_DET_NO_DISP
#define VE_SRC_LR_EDGE_DET_NO_CLK
#define VE_SRC_LR_EDGE_DET_RT
#define VE_SRC_LR_EDGE_DET_INTERLACE

#define VE_SRC_TB_EDGE_DET
#define VE_SRC_TB_EDGE_DET_TOP
#define VE_SRC_TB_EDGE_DET_BOT

#define VE_MODE_DETECT_STATUS
#define VE_MODE_DETECT_H_PERIOD
#define VE_MODE_DETECT_EXTSRC_ADC
#define VE_MODE_DETECT_H_STABLE
#define VE_MODE_DETECT_V_STABLE
#define VE_MODE_DETECT_V_LINES
#define VE_MODE_DETECT_STATUS_VSYNC
#define VE_MODE_DETECT_STATUS_HSYNC
#define VE_MODE_DETECT_VSYNC_RDY
#define VE_MODE_DETECT_HSYNC_RDY

#define VE_SYNC_STATUS
#define VE_SYNC_STATUS_HSYNC
#define VE_SYNC_STATUS_VSYNC

#define VE_H_TOTAL_PIXELS

#define VE_INTERRUPT_CTRL
#define VE_INTERRUPT_STATUS
#define VE_INTERRUPT_MODE_DETECT_WD
#define VE_INTERRUPT_CAPTURE_COMPLETE
#define VE_INTERRUPT_COMP_READY
#define VE_INTERRUPT_COMP_COMPLETE
#define VE_INTERRUPT_MODE_DETECT
#define VE_INTERRUPT_FRAME_COMPLETE
#define VE_INTERRUPT_DECODE_ERR
#define VE_INTERRUPT_HALT_READY
#define VE_INTERRUPT_HANG_WD
#define VE_INTERRUPT_STREAM_DESC
#define VE_INTERRUPT_VSYNC_DESC

#define VE_MODE_DETECT
#define VE_MODE_DT_HOR_TOLER
#define VE_MODE_DT_VER_TOLER
#define VE_MODE_DT_HOR_STABLE
#define VE_MODE_DT_VER_STABLE
#define VE_MODE_DT_EDG_THROD

#define VE_MEM_RESTRICT_START
#define VE_MEM_RESTRICT_END

/*
 * VIDEO_MODE_DETECT_DONE:	a flag raised if signal lock
 * VIDEO_RES_CHANGE:		a flag raised if res_change work on-going
 * VIDEO_RES_DETECT:		a flag raised if res. detection on-going
 * VIDEO_STREAMING:		a flag raised if user requires stream-on
 * VIDEO_FRAME_INPRG:		a flag raised if hw working on a frame
 * VIDEO_STOPPED:		a flag raised if device release
 * VIDEO_CLOCKS_ON:		a flag raised if clk is on
 */
enum {};

enum aspeed_video_format {};

// for VE_CTRL_CAPTURE_FMT
enum aspeed_video_capture_format {};

struct aspeed_video_addr {};

struct aspeed_video_buffer {};

struct aspeed_video_perf {};

#define to_aspeed_video_buffer(x)

/*
 * struct aspeed_video - driver data
 *
 * res_work:		holds the delayed_work for res-detection if unlock
 * buffers:		holds the list of buffer queued from user
 * flags:		holds the state of video
 * sequence:		holds the last number of frame completed
 * max_compressed_size:	holds max compressed stream's size
 * srcs:		holds the buffer information for srcs
 * jpeg:		holds the buffer information for jpeg header
 * bcd:			holds the buffer information for bcd work
 * yuv420:		a flag raised if JPEG subsampling is 420
 * format:		holds the video format
 * hq_mode:		a flag raised if HQ is enabled. Only for VIDEO_FMT_ASPEED
 * frame_rate:		holds the frame_rate
 * jpeg_quality:	holds jpeq's quality (0~11)
 * jpeg_hq_quality:	holds hq's quality (1~12) only if hq_mode enabled
 * frame_bottom:	end position of video data in vertical direction
 * frame_left:		start position of video data in horizontal direction
 * frame_right:		end position of video data in horizontal direction
 * frame_top:		start position of video data in vertical direction
 * perf:		holds the statistics primary for debugfs
 */
struct aspeed_video {};

#define to_aspeed_video(x)

struct aspeed_video_config {};

static const struct aspeed_video_config ast2400_config =;

static const struct aspeed_video_config ast2500_config =;

static const struct aspeed_video_config ast2600_config =;

static const u32 aspeed_video_jpeg_header[ASPEED_VIDEO_JPEG_HEADER_SIZE] =;

static const u32 aspeed_video_jpeg_quant[ASPEED_VIDEO_JPEG_QUANT_SIZE] =;

static const u32 aspeed_video_jpeg_dct[ASPEED_VIDEO_JPEG_NUM_QUALITIES]
				      [ASPEED_VIDEO_JPEG_DCT_SIZE] =;

static const struct v4l2_dv_timings_cap aspeed_video_timings_cap =;

static const char * const format_str[] =;

static unsigned int debug;

static bool aspeed_video_alloc_buf(struct aspeed_video *video,
				   struct aspeed_video_addr *addr,
				   unsigned int size);

static void aspeed_video_free_buf(struct aspeed_video *video,
				  struct aspeed_video_addr *addr);

static void aspeed_video_init_jpeg_table(u32 *table, bool yuv420)
{}

// just update jpeg dct table per 420/444
static void aspeed_video_update_jpeg_table(u32 *table, bool yuv420)
{}

static void aspeed_video_update(struct aspeed_video *video, u32 reg, u32 clear,
				u32 bits)
{}

static u32 aspeed_video_read(struct aspeed_video *video, u32 reg)
{}

static void aspeed_video_write(struct aspeed_video *video, u32 reg, u32 val)
{}

static void update_perf(struct aspeed_video_perf *p)
{}

static int aspeed_video_start_frame(struct aspeed_video *video)
{}

static void aspeed_video_enable_mode_detect(struct aspeed_video *video)
{}

static void aspeed_video_off(struct aspeed_video *video)
{}

static void aspeed_video_on(struct aspeed_video *video)
{}

static void aspeed_video_bufs_done(struct aspeed_video *video,
				   enum vb2_buffer_state state)
{}

static void aspeed_video_irq_res_change(struct aspeed_video *video, ulong delay)
{}

static void aspeed_video_swap_src_buf(struct aspeed_video *v)
{}

static irqreturn_t aspeed_video_irq(int irq, void *arg)
{}

static void aspeed_video_check_and_set_polarity(struct aspeed_video *video)
{}

static bool aspeed_video_alloc_buf(struct aspeed_video *video,
				   struct aspeed_video_addr *addr,
				   unsigned int size)
{}

static void aspeed_video_free_buf(struct aspeed_video *video,
				  struct aspeed_video_addr *addr)
{}

/*
 * Get the minimum HW-supported compression buffer size for the frame size.
 * Assume worst-case JPEG compression size is 1/8 raw size. This should be
 * plenty even for maximum quality; any worse and the engine will simply return
 * incomplete JPEGs.
 */
static void aspeed_video_calc_compressed_size(struct aspeed_video *video,
					      unsigned int frame_size)
{}

/*
 * Update v4l2_bt_timings per current status.
 * frame_top/frame_bottom/frame_left/frame_right need to be ready.
 *
 * The following registers start counting from sync's rising edge:
 * 1. VR090: frame edge's left and right
 * 2. VR094: frame edge's top and bottom
 * 3. VR09C: counting from sync's rising edge to falling edge
 *
 * [Vertical timing]
 *             +--+     +-------------------+     +--+
 *             |  |     |     v i d e o     |     |  |
 *          +--+  +-----+                   +-----+  +---+
 *        vsync+--+
 *    frame_top+--------+
 * frame_bottom+----------------------------+
 *
 *                   +-------------------+
 *                   |     v i d e o     |
 *       +--+  +-----+                   +-----+  +---+
 *          |  |                               |  |
 *          +--+                               +--+
 *        vsync+-------------------------------+
 *    frame_top+-----+
 * frame_bottom+-------------------------+
 *
 * [Horizontal timing]
 *             +--+     +-------------------+     +--+
 *             |  |     |     v i d e o     |     |  |
 *          +--+  +-----+                   +-----+  +---+
 *        hsync+--+
 *   frame_left+--------+
 *  frame_right+----------------------------+
 *
 *                   +-------------------+
 *                   |     v i d e o     |
 *       +--+  +-----+                   +-----+  +---+
 *          |  |                               |  |
 *          +--+                               +--+
 *        hsync+-------------------------------+
 *   frame_left+-----+
 *  frame_right+-------------------------+
 *
 * @v: the struct of aspeed_video
 * @det: v4l2_bt_timings to be updated.
 */
static void aspeed_video_get_timings(struct aspeed_video *v,
				     struct v4l2_bt_timings *det)
{}

#define res_check(v)

static void aspeed_video_get_resolution(struct aspeed_video *video)
{}

static void aspeed_video_set_resolution(struct aspeed_video *video)
{}

static void aspeed_video_update_regs(struct aspeed_video *video)
{}

static void aspeed_video_init_regs(struct aspeed_video *video)
{}

static void aspeed_video_start(struct aspeed_video *video)
{}

static void aspeed_video_stop(struct aspeed_video *video)
{}

static int aspeed_video_querycap(struct file *file, void *fh,
				 struct v4l2_capability *cap)
{}

static int aspeed_video_enum_format(struct file *file, void *fh,
				    struct v4l2_fmtdesc *f)
{}

static int aspeed_video_get_format(struct file *file, void *fh,
				   struct v4l2_format *f)
{}

static int aspeed_video_set_format(struct file *file, void *fh,
				   struct v4l2_format *f)
{}

static int aspeed_video_enum_input(struct file *file, void *fh,
				   struct v4l2_input *inp)
{}

static int aspeed_video_get_input(struct file *file, void *fh, unsigned int *i)
{}

static int aspeed_video_set_input(struct file *file, void *fh, unsigned int i)
{}

static int aspeed_video_get_parm(struct file *file, void *fh,
				 struct v4l2_streamparm *a)
{}

static int aspeed_video_set_parm(struct file *file, void *fh,
				 struct v4l2_streamparm *a)
{}

static int aspeed_video_enum_framesizes(struct file *file, void *fh,
					struct v4l2_frmsizeenum *fsize)
{}

static int aspeed_video_enum_frameintervals(struct file *file, void *fh,
					    struct v4l2_frmivalenum *fival)
{}

static int aspeed_video_set_dv_timings(struct file *file, void *fh,
				       struct v4l2_dv_timings *timings)
{}

static int aspeed_video_get_dv_timings(struct file *file, void *fh,
				       struct v4l2_dv_timings *timings)
{}

static int aspeed_video_query_dv_timings(struct file *file, void *fh,
					 struct v4l2_dv_timings *timings)
{}

static int aspeed_video_enum_dv_timings(struct file *file, void *fh,
					struct v4l2_enum_dv_timings *timings)
{}

static int aspeed_video_dv_timings_cap(struct file *file, void *fh,
				       struct v4l2_dv_timings_cap *cap)
{}

static int aspeed_video_sub_event(struct v4l2_fh *fh,
				  const struct v4l2_event_subscription *sub)
{}

static const struct v4l2_ioctl_ops aspeed_video_ioctl_ops =;

static int aspeed_video_set_ctrl(struct v4l2_ctrl *ctrl)
{}

static const struct v4l2_ctrl_ops aspeed_video_ctrl_ops =;

static const struct v4l2_ctrl_config aspeed_ctrl_HQ_mode =;

static const struct v4l2_ctrl_config aspeed_ctrl_HQ_jpeg_quality =;

static void aspeed_video_resolution_work(struct work_struct *work)
{}

static int aspeed_video_open(struct file *file)
{}

static int aspeed_video_release(struct file *file)
{}

static const struct v4l2_file_operations aspeed_video_v4l2_fops =;

static int aspeed_video_queue_setup(struct vb2_queue *q,
				    unsigned int *num_buffers,
				    unsigned int *num_planes,
				    unsigned int sizes[],
				    struct device *alloc_devs[])
{}

static int aspeed_video_buf_prepare(struct vb2_buffer *vb)
{}

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

static void aspeed_video_stop_streaming(struct vb2_queue *q)
{}

static void aspeed_video_buf_queue(struct vb2_buffer *vb)
{}

static const struct vb2_ops aspeed_video_vb2_ops =;

#ifdef CONFIG_DEBUG_FS
static int aspeed_video_debugfs_show(struct seq_file *s, void *data)
{}
DEFINE_SHOW_ATTRIBUTE();

static struct dentry *debugfs_entry;

static void aspeed_video_debugfs_remove(struct aspeed_video *video)
{}

static void aspeed_video_debugfs_create(struct aspeed_video *video)
{}
#else
static void aspeed_video_debugfs_remove(struct aspeed_video *video) { }
static void aspeed_video_debugfs_create(struct aspeed_video *video) { }
#endif /* CONFIG_DEBUG_FS */

static int aspeed_video_setup_video(struct aspeed_video *video)
{}

static int aspeed_video_init(struct aspeed_video *video)
{}

static const struct of_device_id aspeed_video_of_match[] =;
MODULE_DEVICE_TABLE(of, aspeed_video_of_match);

static int aspeed_video_probe(struct platform_device *pdev)
{}

static void aspeed_video_remove(struct platform_device *pdev)
{}

static struct platform_driver aspeed_video_driver =;

module_platform_driver();

module_param(debug, int, 0644);
MODULE_PARM_DESC();

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