13e7f51bdSMaxime Jourdan /* SPDX-License-Identifier: GPL-2.0+ */ 23e7f51bdSMaxime Jourdan /* 33e7f51bdSMaxime Jourdan * Copyright (C) 2018 BayLibre, SAS 43e7f51bdSMaxime Jourdan * Author: Maxime Jourdan <mjourdan@baylibre.com> 53e7f51bdSMaxime Jourdan */ 63e7f51bdSMaxime Jourdan 73e7f51bdSMaxime Jourdan #ifndef __MESON_VDEC_CORE_H_ 83e7f51bdSMaxime Jourdan #define __MESON_VDEC_CORE_H_ 93e7f51bdSMaxime Jourdan 103e7f51bdSMaxime Jourdan #include <linux/irqreturn.h> 113e7f51bdSMaxime Jourdan #include <linux/regmap.h> 123e7f51bdSMaxime Jourdan #include <linux/list.h> 133e7f51bdSMaxime Jourdan #include <media/videobuf2-v4l2.h> 143e7f51bdSMaxime Jourdan #include <media/v4l2-ctrls.h> 153e7f51bdSMaxime Jourdan #include <media/v4l2-device.h> 163e7f51bdSMaxime Jourdan #include <linux/soc/amlogic/meson-canvas.h> 173e7f51bdSMaxime Jourdan 183e7f51bdSMaxime Jourdan #include "vdec_platform.h" 193e7f51bdSMaxime Jourdan 203e7f51bdSMaxime Jourdan /* 32 buffers in 3-plane YUV420 */ 213e7f51bdSMaxime Jourdan #define MAX_CANVAS (32 * 3) 223e7f51bdSMaxime Jourdan 233e7f51bdSMaxime Jourdan struct amvdec_buffer { 243e7f51bdSMaxime Jourdan struct list_head list; 253e7f51bdSMaxime Jourdan struct vb2_buffer *vb; 263e7f51bdSMaxime Jourdan }; 273e7f51bdSMaxime Jourdan 283e7f51bdSMaxime Jourdan /** 293e7f51bdSMaxime Jourdan * struct amvdec_timestamp - stores a src timestamp along with a VIFIFO offset 303e7f51bdSMaxime Jourdan * 313e7f51bdSMaxime Jourdan * @list: used to make lists out of this struct 32876f123bSMaxime Jourdan * @tc: timecode from the v4l2 buffer 33876f123bSMaxime Jourdan * @ts: timestamp from the VB2 buffer 343e7f51bdSMaxime Jourdan * @offset: offset in the VIFIFO where the associated packet was written 35876f123bSMaxime Jourdan * @flags: flags from the v4l2 buffer 36876f123bSMaxime Jourdan * @used_count: times this timestamp was checked for a match with a dst buffer 373e7f51bdSMaxime Jourdan */ 383e7f51bdSMaxime Jourdan struct amvdec_timestamp { 393e7f51bdSMaxime Jourdan struct list_head list; 40876f123bSMaxime Jourdan struct v4l2_timecode tc; 413e7f51bdSMaxime Jourdan u64 ts; 423e7f51bdSMaxime Jourdan u32 offset; 43876f123bSMaxime Jourdan u32 flags; 44876f123bSMaxime Jourdan u32 used_count; 453e7f51bdSMaxime Jourdan }; 463e7f51bdSMaxime Jourdan 473e7f51bdSMaxime Jourdan struct amvdec_session; 483e7f51bdSMaxime Jourdan 493e7f51bdSMaxime Jourdan /** 503e7f51bdSMaxime Jourdan * struct amvdec_core - device parameters, singleton 513e7f51bdSMaxime Jourdan * 523e7f51bdSMaxime Jourdan * @dos_base: DOS memory base address 533e7f51bdSMaxime Jourdan * @esparser_base: PARSER memory base address 543e7f51bdSMaxime Jourdan * @regmap_ao: regmap for the AO bus 553e7f51bdSMaxime Jourdan * @dev: core device 563e7f51bdSMaxime Jourdan * @dev_dec: decoder device 573e7f51bdSMaxime Jourdan * @platform: platform-specific data 583e7f51bdSMaxime Jourdan * @canvas: canvas provider reference 593e7f51bdSMaxime Jourdan * @dos_parser_clk: DOS_PARSER clock 603e7f51bdSMaxime Jourdan * @dos_clk: DOS clock 613e7f51bdSMaxime Jourdan * @vdec_1_clk: VDEC_1 clock 623e7f51bdSMaxime Jourdan * @vdec_hevc_clk: VDEC_HEVC clock 63*9d45ccf7SHans Verkuil * @vdec_hevcf_clk: VDEC_HEVCF clock 643e7f51bdSMaxime Jourdan * @esparser_reset: RESET for the PARSER 65*9d45ccf7SHans Verkuil * @vdev_dec: video device for the decoder 663e7f51bdSMaxime Jourdan * @v4l2_dev: v4l2 device 673e7f51bdSMaxime Jourdan * @cur_sess: current decoding session 68*9d45ccf7SHans Verkuil * @lock: video device lock 693e7f51bdSMaxime Jourdan */ 703e7f51bdSMaxime Jourdan struct amvdec_core { 713e7f51bdSMaxime Jourdan void __iomem *dos_base; 723e7f51bdSMaxime Jourdan void __iomem *esparser_base; 733e7f51bdSMaxime Jourdan struct regmap *regmap_ao; 743e7f51bdSMaxime Jourdan 753e7f51bdSMaxime Jourdan struct device *dev; 763e7f51bdSMaxime Jourdan struct device *dev_dec; 773e7f51bdSMaxime Jourdan const struct vdec_platform *platform; 783e7f51bdSMaxime Jourdan 793e7f51bdSMaxime Jourdan struct meson_canvas *canvas; 803e7f51bdSMaxime Jourdan 813e7f51bdSMaxime Jourdan struct clk *dos_parser_clk; 823e7f51bdSMaxime Jourdan struct clk *dos_clk; 833e7f51bdSMaxime Jourdan struct clk *vdec_1_clk; 843e7f51bdSMaxime Jourdan struct clk *vdec_hevc_clk; 858299c653SMaxime Jourdan struct clk *vdec_hevcf_clk; 863e7f51bdSMaxime Jourdan 873e7f51bdSMaxime Jourdan struct reset_control *esparser_reset; 883e7f51bdSMaxime Jourdan 893e7f51bdSMaxime Jourdan struct video_device *vdev_dec; 903e7f51bdSMaxime Jourdan struct v4l2_device v4l2_dev; 913e7f51bdSMaxime Jourdan 923e7f51bdSMaxime Jourdan struct amvdec_session *cur_sess; 93*9d45ccf7SHans Verkuil struct mutex lock; 943e7f51bdSMaxime Jourdan }; 953e7f51bdSMaxime Jourdan 963e7f51bdSMaxime Jourdan /** 973e7f51bdSMaxime Jourdan * struct amvdec_ops - vdec operations 983e7f51bdSMaxime Jourdan * 993e7f51bdSMaxime Jourdan * @start: mandatory call when the vdec needs to initialize 1003e7f51bdSMaxime Jourdan * @stop: mandatory call when the vdec needs to stop 1013e7f51bdSMaxime Jourdan * @conf_esparser: mandatory call to let the vdec configure the ESPARSER 1023e7f51bdSMaxime Jourdan * @vififo_level: mandatory call to get the current amount of data 1033e7f51bdSMaxime Jourdan * in the VIFIFO 1043e7f51bdSMaxime Jourdan * @use_offsets: mandatory call. Returns 1 if the VDEC supports vififo offsets 1053e7f51bdSMaxime Jourdan */ 1063e7f51bdSMaxime Jourdan struct amvdec_ops { 1073e7f51bdSMaxime Jourdan int (*start)(struct amvdec_session *sess); 1083e7f51bdSMaxime Jourdan int (*stop)(struct amvdec_session *sess); 1093e7f51bdSMaxime Jourdan void (*conf_esparser)(struct amvdec_session *sess); 1103e7f51bdSMaxime Jourdan u32 (*vififo_level)(struct amvdec_session *sess); 1113e7f51bdSMaxime Jourdan }; 1123e7f51bdSMaxime Jourdan 1133e7f51bdSMaxime Jourdan /** 1143e7f51bdSMaxime Jourdan * struct amvdec_codec_ops - codec operations 1153e7f51bdSMaxime Jourdan * 1163e7f51bdSMaxime Jourdan * @start: mandatory call when the codec needs to initialize 1173e7f51bdSMaxime Jourdan * @stop: mandatory call when the codec needs to stop 1183e7f51bdSMaxime Jourdan * @load_extended_firmware: optional call to load additional firmware bits 1193e7f51bdSMaxime Jourdan * @num_pending_bufs: optional call to get the number of dst buffers on hold 1203e7f51bdSMaxime Jourdan * @can_recycle: optional call to know if the codec is ready to recycle 1213e7f51bdSMaxime Jourdan * a dst buffer 1223e7f51bdSMaxime Jourdan * @recycle: optional call to tell the codec to recycle a dst buffer. Must go 1233e7f51bdSMaxime Jourdan * in pair with @can_recycle 1243e7f51bdSMaxime Jourdan * @drain: optional call if the codec has a custom way of draining 125*9d45ccf7SHans Verkuil * @resume: optional call to resume after a resolution change 1263e7f51bdSMaxime Jourdan * @eos_sequence: optional call to get an end sequence to send to esparser 1273e7f51bdSMaxime Jourdan * for flush. Mutually exclusive with @drain. 1283e7f51bdSMaxime Jourdan * @isr: mandatory call when the ISR triggers 1293e7f51bdSMaxime Jourdan * @threaded_isr: mandatory call for the threaded ISR 1303e7f51bdSMaxime Jourdan */ 1313e7f51bdSMaxime Jourdan struct amvdec_codec_ops { 1323e7f51bdSMaxime Jourdan int (*start)(struct amvdec_session *sess); 1333e7f51bdSMaxime Jourdan int (*stop)(struct amvdec_session *sess); 1343e7f51bdSMaxime Jourdan int (*load_extended_firmware)(struct amvdec_session *sess, 1353e7f51bdSMaxime Jourdan const u8 *data, u32 len); 1363e7f51bdSMaxime Jourdan u32 (*num_pending_bufs)(struct amvdec_session *sess); 1373e7f51bdSMaxime Jourdan int (*can_recycle)(struct amvdec_core *core); 1383e7f51bdSMaxime Jourdan void (*recycle)(struct amvdec_core *core, u32 buf_idx); 1393e7f51bdSMaxime Jourdan void (*drain)(struct amvdec_session *sess); 1403e7f51bdSMaxime Jourdan void (*resume)(struct amvdec_session *sess); 1413e7f51bdSMaxime Jourdan const u8 * (*eos_sequence)(u32 *len); 1423e7f51bdSMaxime Jourdan irqreturn_t (*isr)(struct amvdec_session *sess); 1433e7f51bdSMaxime Jourdan irqreturn_t (*threaded_isr)(struct amvdec_session *sess); 1443e7f51bdSMaxime Jourdan }; 1453e7f51bdSMaxime Jourdan 1463e7f51bdSMaxime Jourdan /** 1473e7f51bdSMaxime Jourdan * struct amvdec_format - describes one of the OUTPUT (src) format supported 1483e7f51bdSMaxime Jourdan * 1493e7f51bdSMaxime Jourdan * @pixfmt: V4L2 pixel format 1503e7f51bdSMaxime Jourdan * @min_buffers: minimum amount of CAPTURE (dst) buffers 1513e7f51bdSMaxime Jourdan * @max_buffers: maximum amount of CAPTURE (dst) buffers 1523e7f51bdSMaxime Jourdan * @max_width: maximum picture width supported 1533e7f51bdSMaxime Jourdan * @max_height: maximum picture height supported 1543e7f51bdSMaxime Jourdan * @flags: enum flags associated with this pixfmt 1553e7f51bdSMaxime Jourdan * @vdec_ops: the VDEC operations that support this format 1563e7f51bdSMaxime Jourdan * @codec_ops: the codec operations that support this format 1573e7f51bdSMaxime Jourdan * @firmware_path: Path to the firmware that supports this format 1583e7f51bdSMaxime Jourdan * @pixfmts_cap: list of CAPTURE pixel formats available with pixfmt 1593e7f51bdSMaxime Jourdan */ 1603e7f51bdSMaxime Jourdan struct amvdec_format { 1613e7f51bdSMaxime Jourdan u32 pixfmt; 1623e7f51bdSMaxime Jourdan u32 min_buffers; 1633e7f51bdSMaxime Jourdan u32 max_buffers; 1643e7f51bdSMaxime Jourdan u32 max_width; 1653e7f51bdSMaxime Jourdan u32 max_height; 1663e7f51bdSMaxime Jourdan u32 flags; 1673e7f51bdSMaxime Jourdan 1683e7f51bdSMaxime Jourdan struct amvdec_ops *vdec_ops; 1693e7f51bdSMaxime Jourdan struct amvdec_codec_ops *codec_ops; 1703e7f51bdSMaxime Jourdan 1713e7f51bdSMaxime Jourdan char *firmware_path; 1723e7f51bdSMaxime Jourdan u32 pixfmts_cap[4]; 1733e7f51bdSMaxime Jourdan }; 1743e7f51bdSMaxime Jourdan 1753e7f51bdSMaxime Jourdan enum amvdec_status { 1763e7f51bdSMaxime Jourdan STATUS_STOPPED, 177876f123bSMaxime Jourdan STATUS_INIT, 1783e7f51bdSMaxime Jourdan STATUS_RUNNING, 1793e7f51bdSMaxime Jourdan STATUS_NEEDS_RESUME, 1803e7f51bdSMaxime Jourdan }; 1813e7f51bdSMaxime Jourdan 1823e7f51bdSMaxime Jourdan /** 1833e7f51bdSMaxime Jourdan * struct amvdec_session - decoding session parameters 1843e7f51bdSMaxime Jourdan * 1853e7f51bdSMaxime Jourdan * @core: reference to the vdec core struct 1863e7f51bdSMaxime Jourdan * @fh: v4l2 file handle 1873e7f51bdSMaxime Jourdan * @m2m_dev: v4l2 m2m device 1883e7f51bdSMaxime Jourdan * @m2m_ctx: v4l2 m2m context 1893e7f51bdSMaxime Jourdan * @ctrl_handler: V4L2 control handler 1903e7f51bdSMaxime Jourdan * @ctrl_min_buf_capture: V4L2 control V4L2_CID_MIN_BUFFERS_FOR_CAPTURE 191*9d45ccf7SHans Verkuil * @lock: cap & out queues lock 1923e7f51bdSMaxime Jourdan * @fmt_out: vdec pixel format for the OUTPUT queue 1933e7f51bdSMaxime Jourdan * @pixfmt_cap: V4L2 pixel format for the CAPTURE queue 194876f123bSMaxime Jourdan * @src_buffer_size: size in bytes of the OUTPUT buffers' only plane 1953e7f51bdSMaxime Jourdan * @width: current picture width 1963e7f51bdSMaxime Jourdan * @height: current picture height 1973e7f51bdSMaxime Jourdan * @colorspace: current colorspace 1983e7f51bdSMaxime Jourdan * @ycbcr_enc: current ycbcr_enc 1993e7f51bdSMaxime Jourdan * @quantization: current quantization 2003e7f51bdSMaxime Jourdan * @xfer_func: current transfer function 2013e7f51bdSMaxime Jourdan * @pixelaspect: Pixel Aspect Ratio reported by the decoder 2023e7f51bdSMaxime Jourdan * @esparser_queued_bufs: number of buffers currently queued into ESPARSER 2033e7f51bdSMaxime Jourdan * @esparser_queue_work: work struct for the ESPARSER to process src buffers 2043e7f51bdSMaxime Jourdan * @streamon_cap: stream on flag for capture queue 2053e7f51bdSMaxime Jourdan * @streamon_out: stream on flag for output queue 2063e7f51bdSMaxime Jourdan * @sequence_cap: capture sequence counter 207*9d45ccf7SHans Verkuil * @sequence_out: output sequence counter 2083e7f51bdSMaxime Jourdan * @should_stop: flag set if userspace signaled EOS via command 2093e7f51bdSMaxime Jourdan * or empty buffer 2103e7f51bdSMaxime Jourdan * @keyframe_found: flag set once a keyframe has been parsed 211*9d45ccf7SHans Verkuil * @num_dst_bufs: number of destination buffers 212*9d45ccf7SHans Verkuil * @changed_format: the format changed 2133e7f51bdSMaxime Jourdan * @canvas_alloc: array of all the canvas IDs allocated 2143e7f51bdSMaxime Jourdan * @canvas_num: number of canvas IDs allocated 2153e7f51bdSMaxime Jourdan * @vififo_vaddr: virtual address for the VIFIFO 2163e7f51bdSMaxime Jourdan * @vififo_paddr: physical address for the VIFIFO 2173e7f51bdSMaxime Jourdan * @vififo_size: size of the VIFIFO dma alloc 2183e7f51bdSMaxime Jourdan * @bufs_recycle: list of buffers that need to be recycled 2193e7f51bdSMaxime Jourdan * @bufs_recycle_lock: lock for the bufs_recycle list 2203e7f51bdSMaxime Jourdan * @recycle_thread: task struct for the recycling thread 2213e7f51bdSMaxime Jourdan * @timestamps: chronological list of src timestamps 2223e7f51bdSMaxime Jourdan * @ts_spinlock: spinlock for the timestamps list 2233e7f51bdSMaxime Jourdan * @last_irq_jiffies: tracks last time the vdec triggered an IRQ 224*9d45ccf7SHans Verkuil * @last_offset: tracks last offset of vififo 225*9d45ccf7SHans Verkuil * @wrap_count: number of times the vififo wrapped around 226*9d45ccf7SHans Verkuil * @fw_idx_to_vb2_idx: firmware buffer index to vb2 buffer index 2273e7f51bdSMaxime Jourdan * @status: current decoding status 2283e7f51bdSMaxime Jourdan * @priv: codec private data 2293e7f51bdSMaxime Jourdan */ 2303e7f51bdSMaxime Jourdan struct amvdec_session { 2313e7f51bdSMaxime Jourdan struct amvdec_core *core; 2323e7f51bdSMaxime Jourdan 2333e7f51bdSMaxime Jourdan struct v4l2_fh fh; 2343e7f51bdSMaxime Jourdan struct v4l2_m2m_dev *m2m_dev; 2353e7f51bdSMaxime Jourdan struct v4l2_m2m_ctx *m2m_ctx; 2363e7f51bdSMaxime Jourdan struct v4l2_ctrl_handler ctrl_handler; 2373e7f51bdSMaxime Jourdan struct v4l2_ctrl *ctrl_min_buf_capture; 238*9d45ccf7SHans Verkuil struct mutex lock; 2393e7f51bdSMaxime Jourdan 2403e7f51bdSMaxime Jourdan const struct amvdec_format *fmt_out; 2413e7f51bdSMaxime Jourdan u32 pixfmt_cap; 242876f123bSMaxime Jourdan u32 src_buffer_size; 2433e7f51bdSMaxime Jourdan 2443e7f51bdSMaxime Jourdan u32 width; 2453e7f51bdSMaxime Jourdan u32 height; 2463e7f51bdSMaxime Jourdan u32 colorspace; 2473e7f51bdSMaxime Jourdan u8 ycbcr_enc; 2483e7f51bdSMaxime Jourdan u8 quantization; 2493e7f51bdSMaxime Jourdan u8 xfer_func; 2503e7f51bdSMaxime Jourdan 2513e7f51bdSMaxime Jourdan struct v4l2_fract pixelaspect; 2523e7f51bdSMaxime Jourdan 2533e7f51bdSMaxime Jourdan atomic_t esparser_queued_bufs; 2543e7f51bdSMaxime Jourdan struct work_struct esparser_queue_work; 2553e7f51bdSMaxime Jourdan 2563e7f51bdSMaxime Jourdan unsigned int streamon_cap, streamon_out; 257876f123bSMaxime Jourdan unsigned int sequence_cap, sequence_out; 2583e7f51bdSMaxime Jourdan unsigned int should_stop; 2593e7f51bdSMaxime Jourdan unsigned int keyframe_found; 2603e7f51bdSMaxime Jourdan unsigned int num_dst_bufs; 261876f123bSMaxime Jourdan unsigned int changed_format; 2623e7f51bdSMaxime Jourdan 2633e7f51bdSMaxime Jourdan u8 canvas_alloc[MAX_CANVAS]; 2643e7f51bdSMaxime Jourdan u32 canvas_num; 2653e7f51bdSMaxime Jourdan 2663e7f51bdSMaxime Jourdan void *vififo_vaddr; 2673e7f51bdSMaxime Jourdan dma_addr_t vififo_paddr; 2683e7f51bdSMaxime Jourdan u32 vififo_size; 2693e7f51bdSMaxime Jourdan 2703e7f51bdSMaxime Jourdan struct list_head bufs_recycle; 2713e7f51bdSMaxime Jourdan struct mutex bufs_recycle_lock; /* bufs_recycle list lock */ 2723e7f51bdSMaxime Jourdan struct task_struct *recycle_thread; 2733e7f51bdSMaxime Jourdan 2743e7f51bdSMaxime Jourdan struct list_head timestamps; 2753e7f51bdSMaxime Jourdan spinlock_t ts_spinlock; /* timestamp list lock */ 2763e7f51bdSMaxime Jourdan 2773e7f51bdSMaxime Jourdan u64 last_irq_jiffies; 2783e7f51bdSMaxime Jourdan u32 last_offset; 2793e7f51bdSMaxime Jourdan u32 wrap_count; 2803e7f51bdSMaxime Jourdan u32 fw_idx_to_vb2_idx[32]; 2813e7f51bdSMaxime Jourdan 2823e7f51bdSMaxime Jourdan enum amvdec_status status; 2833e7f51bdSMaxime Jourdan void *priv; 2843e7f51bdSMaxime Jourdan }; 2853e7f51bdSMaxime Jourdan 2863e7f51bdSMaxime Jourdan u32 amvdec_get_output_size(struct amvdec_session *sess); 2873e7f51bdSMaxime Jourdan 2883e7f51bdSMaxime Jourdan #endif 289