| /* SPDX-License-Identifier: GPL-2.0+ */ |
| /* |
| * Copyright (C) 2018 BayLibre, SAS |
| * Author: Maxime Jourdan <mjourdan@baylibre.com> |
| */ |
| |
| #ifndef __MESON_VDEC_CORE_H_ |
| #define __MESON_VDEC_CORE_H_ |
| |
| #include <linux/irqreturn.h> |
| #include <linux/regmap.h> |
| #include <linux/list.h> |
| #include <media/videobuf2-v4l2.h> |
| #include <media/v4l2-ctrls.h> |
| #include <media/v4l2-device.h> |
| #include <linux/soc/amlogic/meson-canvas.h> |
| |
| #include "vdec_platform.h" |
| |
| /* 32 buffers in 3-plane YUV420 */ |
| #define MAX_CANVAS (32 * 3) |
| |
| struct amvdec_buffer { |
| struct list_head list; |
| struct vb2_buffer *vb; |
| }; |
| |
| /** |
| * struct amvdec_timestamp - stores a src timestamp along with a VIFIFO offset |
| * |
| * @list: used to make lists out of this struct |
| * @tc: timecode from the v4l2 buffer |
| * @ts: timestamp from the VB2 buffer |
| * @offset: offset in the VIFIFO where the associated packet was written |
| * @flags: flags from the v4l2 buffer |
| * @used_count: times this timestamp was checked for a match with a dst buffer |
| */ |
| struct amvdec_timestamp { |
| struct list_head list; |
| struct v4l2_timecode tc; |
| u64 ts; |
| u32 offset; |
| u32 flags; |
| u32 used_count; |
| }; |
| |
| struct amvdec_session; |
| |
| /** |
| * struct amvdec_core - device parameters, singleton |
| * |
| * @dos_base: DOS memory base address |
| * @esparser_base: PARSER memory base address |
| * @regmap_ao: regmap for the AO bus |
| * @dev: core device |
| * @dev_dec: decoder device |
| * @platform: platform-specific data |
| * @canvas: canvas provider reference |
| * @dos_parser_clk: DOS_PARSER clock |
| * @dos_clk: DOS clock |
| * @vdec_1_clk: VDEC_1 clock |
| * @vdec_hevc_clk: VDEC_HEVC clock |
| * @esparser_reset: RESET for the PARSER |
| * @vdec_dec: video device for the decoder |
| * @v4l2_dev: v4l2 device |
| * @cur_sess: current decoding session |
| */ |
| struct amvdec_core { |
| void __iomem *dos_base; |
| void __iomem *esparser_base; |
| struct regmap *regmap_ao; |
| |
| struct device *dev; |
| struct device *dev_dec; |
| const struct vdec_platform *platform; |
| |
| struct meson_canvas *canvas; |
| |
| struct clk *dos_parser_clk; |
| struct clk *dos_clk; |
| struct clk *vdec_1_clk; |
| struct clk *vdec_hevc_clk; |
| struct clk *vdec_hevcf_clk; |
| |
| struct reset_control *esparser_reset; |
| |
| struct video_device *vdev_dec; |
| struct v4l2_device v4l2_dev; |
| |
| struct amvdec_session *cur_sess; |
| struct mutex lock; /* video device lock */ |
| }; |
| |
| /** |
| * struct amvdec_ops - vdec operations |
| * |
| * @start: mandatory call when the vdec needs to initialize |
| * @stop: mandatory call when the vdec needs to stop |
| * @conf_esparser: mandatory call to let the vdec configure the ESPARSER |
| * @vififo_level: mandatory call to get the current amount of data |
| * in the VIFIFO |
| * @use_offsets: mandatory call. Returns 1 if the VDEC supports vififo offsets |
| */ |
| struct amvdec_ops { |
| int (*start)(struct amvdec_session *sess); |
| int (*stop)(struct amvdec_session *sess); |
| void (*conf_esparser)(struct amvdec_session *sess); |
| u32 (*vififo_level)(struct amvdec_session *sess); |
| }; |
| |
| /** |
| * struct amvdec_codec_ops - codec operations |
| * |
| * @start: mandatory call when the codec needs to initialize |
| * @stop: mandatory call when the codec needs to stop |
| * @load_extended_firmware: optional call to load additional firmware bits |
| * @num_pending_bufs: optional call to get the number of dst buffers on hold |
| * @can_recycle: optional call to know if the codec is ready to recycle |
| * a dst buffer |
| * @recycle: optional call to tell the codec to recycle a dst buffer. Must go |
| * in pair with @can_recycle |
| * @drain: optional call if the codec has a custom way of draining |
| * @eos_sequence: optional call to get an end sequence to send to esparser |
| * for flush. Mutually exclusive with @drain. |
| * @isr: mandatory call when the ISR triggers |
| * @threaded_isr: mandatory call for the threaded ISR |
| */ |
| struct amvdec_codec_ops { |
| int (*start)(struct amvdec_session *sess); |
| int (*stop)(struct amvdec_session *sess); |
| int (*load_extended_firmware)(struct amvdec_session *sess, |
| const u8 *data, u32 len); |
| u32 (*num_pending_bufs)(struct amvdec_session *sess); |
| int (*can_recycle)(struct amvdec_core *core); |
| void (*recycle)(struct amvdec_core *core, u32 buf_idx); |
| void (*drain)(struct amvdec_session *sess); |
| void (*resume)(struct amvdec_session *sess); |
| const u8 * (*eos_sequence)(u32 *len); |
| irqreturn_t (*isr)(struct amvdec_session *sess); |
| irqreturn_t (*threaded_isr)(struct amvdec_session *sess); |
| }; |
| |
| /** |
| * struct amvdec_format - describes one of the OUTPUT (src) format supported |
| * |
| * @pixfmt: V4L2 pixel format |
| * @min_buffers: minimum amount of CAPTURE (dst) buffers |
| * @max_buffers: maximum amount of CAPTURE (dst) buffers |
| * @max_width: maximum picture width supported |
| * @max_height: maximum picture height supported |
| * @flags: enum flags associated with this pixfmt |
| * @vdec_ops: the VDEC operations that support this format |
| * @codec_ops: the codec operations that support this format |
| * @firmware_path: Path to the firmware that supports this format |
| * @pixfmts_cap: list of CAPTURE pixel formats available with pixfmt |
| */ |
| struct amvdec_format { |
| u32 pixfmt; |
| u32 min_buffers; |
| u32 max_buffers; |
| u32 max_width; |
| u32 max_height; |
| u32 flags; |
| |
| struct amvdec_ops *vdec_ops; |
| struct amvdec_codec_ops *codec_ops; |
| |
| char *firmware_path; |
| u32 pixfmts_cap[4]; |
| }; |
| |
| enum amvdec_status { |
| STATUS_STOPPED, |
| STATUS_INIT, |
| STATUS_RUNNING, |
| STATUS_NEEDS_RESUME, |
| }; |
| |
| /** |
| * struct amvdec_session - decoding session parameters |
| * |
| * @core: reference to the vdec core struct |
| * @fh: v4l2 file handle |
| * @m2m_dev: v4l2 m2m device |
| * @m2m_ctx: v4l2 m2m context |
| * @ctrl_handler: V4L2 control handler |
| * @ctrl_min_buf_capture: V4L2 control V4L2_CID_MIN_BUFFERS_FOR_CAPTURE |
| * @fmt_out: vdec pixel format for the OUTPUT queue |
| * @pixfmt_cap: V4L2 pixel format for the CAPTURE queue |
| * @src_buffer_size: size in bytes of the OUTPUT buffers' only plane |
| * @width: current picture width |
| * @height: current picture height |
| * @colorspace: current colorspace |
| * @ycbcr_enc: current ycbcr_enc |
| * @quantization: current quantization |
| * @xfer_func: current transfer function |
| * @pixelaspect: Pixel Aspect Ratio reported by the decoder |
| * @esparser_queued_bufs: number of buffers currently queued into ESPARSER |
| * @esparser_queue_work: work struct for the ESPARSER to process src buffers |
| * @streamon_cap: stream on flag for capture queue |
| * @streamon_out: stream on flag for output queue |
| * @sequence_cap: capture sequence counter |
| * @should_stop: flag set if userspace signaled EOS via command |
| * or empty buffer |
| * @keyframe_found: flag set once a keyframe has been parsed |
| * @canvas_alloc: array of all the canvas IDs allocated |
| * @canvas_num: number of canvas IDs allocated |
| * @vififo_vaddr: virtual address for the VIFIFO |
| * @vififo_paddr: physical address for the VIFIFO |
| * @vififo_size: size of the VIFIFO dma alloc |
| * @bufs_recycle: list of buffers that need to be recycled |
| * @bufs_recycle_lock: lock for the bufs_recycle list |
| * @recycle_thread: task struct for the recycling thread |
| * @timestamps: chronological list of src timestamps |
| * @ts_spinlock: spinlock for the timestamps list |
| * @last_irq_jiffies: tracks last time the vdec triggered an IRQ |
| * @status: current decoding status |
| * @priv: codec private data |
| */ |
| struct amvdec_session { |
| struct amvdec_core *core; |
| |
| struct v4l2_fh fh; |
| struct v4l2_m2m_dev *m2m_dev; |
| struct v4l2_m2m_ctx *m2m_ctx; |
| struct v4l2_ctrl_handler ctrl_handler; |
| struct v4l2_ctrl *ctrl_min_buf_capture; |
| struct mutex lock; /* cap & out queues lock */ |
| |
| const struct amvdec_format *fmt_out; |
| u32 pixfmt_cap; |
| u32 src_buffer_size; |
| |
| u32 width; |
| u32 height; |
| u32 colorspace; |
| u8 ycbcr_enc; |
| u8 quantization; |
| u8 xfer_func; |
| |
| struct v4l2_fract pixelaspect; |
| |
| atomic_t esparser_queued_bufs; |
| struct work_struct esparser_queue_work; |
| |
| unsigned int streamon_cap, streamon_out; |
| unsigned int sequence_cap, sequence_out; |
| unsigned int should_stop; |
| unsigned int keyframe_found; |
| unsigned int num_dst_bufs; |
| unsigned int changed_format; |
| |
| u8 canvas_alloc[MAX_CANVAS]; |
| u32 canvas_num; |
| |
| void *vififo_vaddr; |
| dma_addr_t vififo_paddr; |
| u32 vififo_size; |
| |
| struct list_head bufs_recycle; |
| struct mutex bufs_recycle_lock; /* bufs_recycle list lock */ |
| struct task_struct *recycle_thread; |
| |
| struct list_head timestamps; |
| spinlock_t ts_spinlock; /* timestamp list lock */ |
| |
| u64 last_irq_jiffies; |
| u32 last_offset; |
| u32 wrap_count; |
| u32 fw_idx_to_vb2_idx[32]; |
| |
| enum amvdec_status status; |
| void *priv; |
| }; |
| |
| u32 amvdec_get_output_size(struct amvdec_session *sess); |
| |
| #endif |