diff options
Diffstat (limited to 'drivers/mxc/vpu_malone/vpu_b0.h')
-rw-r--r-- | drivers/mxc/vpu_malone/vpu_b0.h | 539 |
1 files changed, 539 insertions, 0 deletions
diff --git a/drivers/mxc/vpu_malone/vpu_b0.h b/drivers/mxc/vpu_malone/vpu_b0.h new file mode 100644 index 000000000000..3d7ca75c5746 --- /dev/null +++ b/drivers/mxc/vpu_malone/vpu_b0.h @@ -0,0 +1,539 @@ +/* + * Copyright 2018-2020 NXP + */ + +/* + * The code contained herein is licensed under the GNU General Public + * License. You may obtain a copy of the GNU General Public License + * Version 2 or later at the following locations: + * + * http://www.opensource.org/licenses/gpl-license.html + * http://www.gnu.org/copyleft/gpl.html + */ + +/*! + * @file vpu_b0.h + * + * @brief VPU B0 definition + * + */ +#ifndef __VPU_B0_H +#define __VPU_B0_H + +#include <linux/version.h> +#include <linux/irqreturn.h> +#include <linux/mutex.h> +#include <linux/videodev2.h> +#include <media/v4l2-ctrls.h> +#include <media/v4l2-device.h> +#include <media/v4l2-fh.h> +#include <media/videobuf2-v4l2.h> +#ifdef CONFIG_IMX_SCU +#include <linux/firmware/imx/ipc.h> +#include <linux/firmware/imx/svc/misc.h> +#else +#include <soc/imx8/sc/svc/irq/api.h> +#include <soc/imx8/sc/ipc.h> +#include <soc/imx8/sc/sci.h> +#endif +#include <linux/mx8_mu.h> +#include <linux/mailbox_client.h> +#include <media/v4l2-event.h> +#include <linux/kfifo.h> +#include "vpu_rpc.h" + +extern unsigned int vpu_dbg_level_decoder; + +#define v4l2_fh_to_ctx(__fh) \ + container_of(__fh, struct vpu_ctx, fh) +#define v4l2_ctrl_to_ctx(__ctrl) \ + container_of((__ctrl)->handler, struct vpu_ctx, ctrl_handler) + +#define MIN_SPACE (SCODE_SIZE + 64) +#define SCODE_SIZE (4096) + +#define VPU_MAX_BUFFER 32 +#define M0FW_FILENAME "vpu/vpu_fw_imx8_dec.bin" +#define MMAP_BUF_TYPE_SHIFT 28 +#define MMAP_BUF_TYPE_MASK 0xF0000000 +#define DCP_SIZE 0x3000000 +#define DCP_SIZE_MINIMUM 0x100000 +#define MAX_BUFFER_SIZE 0xc00000 +#define UDATA_BUFFER_SIZE 0x1000 +#define MAX_DCP_NUM 2 +#define MAX_MBI_NUM 18 // same with MEDIA_PLAYER_MAX_MBI_UNIT defined in firmware +#define MAX_TIMEOUT_COUNT 10 +#define VPU_REG_BASE 0x40000000 +#define VPU_MAX_STEP_STRING_LENGTH 40 +#define VPU_DISABLE_BITS (0x7) + +#define V4L2_PIX_FMT_NV12_10BIT v4l2_fourcc('N', 'T', '1', '2') /* Y/CbCr 4:2:0 for 10bit */ +#define VPU_FRAME_DEPTH_MAX 512 +#define VPU_FRAME_DEPTH_DEFAULT 256 +#define DECODER_NODE_NUMBER 12 // use /dev/video12 as vpu decoder +#define DEFAULT_LOG_DEPTH 20 +#define DEFAULT_FRMDBG_ENABLE 0 +#define DEFAULT_FRMDBG_LEVEL 0 +#define VPU_DEC_CMD_DATA_MAX_NUM 16 +#define VPU_DEC_MAX_WIDTH 8188 +#define VPU_DEC_MAX_HEIGTH 8188 +#define VPU_DEC_FMT_DIVX_MASK (1 << 20) +#define VPU_DEC_FMT_RV_MASK (1 << 21) + +#define V4L2_EVENT_DECODE_ERROR (V4L2_EVENT_PRIVATE_START + 1) +#define V4L2_EVENT_SKIP (V4L2_EVENT_PRIVATE_START + 2) + +struct vpu_v4l2_control { + uint32_t id; + enum v4l2_ctrl_type type; + uint32_t minimum; + uint32_t maximum; + uint32_t step; + uint32_t default_value; + uint32_t menu_skip_mask; + bool is_volatile; +}; + +typedef enum{ + INIT_DONE = 1, + RPC_BUF_OFFSET, + BOOT_ADDRESS, + COMMAND, + EVENT +} MSG_Type; + +enum PLAT_TYPE { + IMX8QXP = 0, + IMX8QM = 1, +}; + +enum QUEUE_TYPE { + V4L2_SRC = 0, + V4L2_DST = 1, +}; + +enum vpu_video_standard { + VPU_VIDEO_UNDEFINED = 0, + VPU_VIDEO_AVC = 1, + VPU_VIDEO_VC1 = 2, + VPU_VIDEO_MPEG2 = 3, + VPU_VIDEO_AVS = 4, + VPU_VIDEO_ASP = 5, + VPU_VIDEO_JPEG = 6, + VPU_VIDEO_RV = 7, + VPU_VIDEO_VP6 = 8, + VPU_VIDEO_SPK = 9, + VPU_VIDEO_VP8 = 10, + VPU_VIDEO_AVC_MVC = 11, + VPU_VIDEO_HEVC = 12, +}; + +typedef enum{ + EOS_PADDING_TYPE = 1, + BUFFLUSH_PADDING_TYPE = 2, + BUFABORT_PADDING_TYPE = 3, +} VPU_PADDING_SCODE_TYPE; + +#define VPU_PIX_FMT_AVS v4l2_fourcc('A', 'V', 'S', '0') +#define VPU_PIX_FMT_ASP v4l2_fourcc('A', 'S', 'P', '0') +#define VPU_PIX_FMT_RV v4l2_fourcc('R', 'V', '0', '0') +#define VPU_PIX_FMT_VP6 v4l2_fourcc('V', 'P', '6', '0') +#define VPU_PIX_FMT_SPK v4l2_fourcc('S', 'P', 'K', '0') +#define VPU_PIX_FMT_DIV3 v4l2_fourcc('D', 'I', 'V', '3') +#define VPU_PIX_FMT_DIVX v4l2_fourcc('D', 'I', 'V', 'X') +#define VPU_PIX_FMT_HEVC v4l2_fourcc('H', 'E', 'V', 'C') +#define VPU_PIX_FMT_LOGO v4l2_fourcc('L', 'O', 'G', 'O') + +#define VPU_PIX_FMT_TILED_8 v4l2_fourcc('Z', 'T', '0', '8') +#define VPU_PIX_FMT_TILED_10 v4l2_fourcc('Z', 'T', '1', '0') + +#define V4L2_CID_USER_RAW_BASE (V4L2_CID_USER_BASE + 0x1100) +#define V4L2_CID_USER_FRAME_DEPTH (V4L2_CID_USER_BASE + 0x1200) +#define V4L2_CID_USER_FRAME_DIS_REORDER (V4L2_CID_USER_BASE + 0x1300) +#define V4L2_CID_USER_TS_THRESHOLD (V4L2_CID_USER_BASE + 0x1101) +#define V4L2_CID_USER_BS_L_THRESHOLD (V4L2_CID_USER_BASE + 0x1102) +#define V4L2_CID_USER_BS_H_THRESHOLD (V4L2_CID_USER_BASE + 0x1103) + +#define V4L2_CID_USER_FRAME_COLORDESC (V4L2_CID_USER_BASE + 0x1104) +#define V4L2_CID_USER_FRAME_TRANSFERCHARS (V4L2_CID_USER_BASE + 0x1105) +#define V4L2_CID_USER_FRAME_MATRIXCOEFFS (V4L2_CID_USER_BASE + 0x1106) +#define V4L2_CID_USER_FRAME_FULLRANGE (V4L2_CID_USER_BASE + 0x1107) +#define V4L2_CID_USER_FRAME_VUIPRESENT (V4L2_CID_USER_BASE + 0x1108) + +#define V4L2_CID_USER_STREAM_INPUT_MODE (V4L2_CID_USER_BASE + 0x1109) +#define V4L2_CID_USER_FRAME_THRESHOLD (V4L2_CID_USER_BASE + 0x110A) + +#define IMX_V4L2_DEC_CMD_START (0x09000000) +#define IMX_V4L2_DEC_CMD_RESET (IMX_V4L2_DEC_CMD_START + 1) + +enum vpu_pixel_format { + VPU_HAS_COLOCATED = 0x00000001, + VPU_HAS_SPLIT_FLD = 0x00000002, + VPU_PF_MASK = ~(VPU_HAS_COLOCATED | VPU_HAS_SPLIT_FLD), + + VPU_IS_TILED = 0x000000100, + VPU_HAS_10BPP = 0x00000200, + + VPU_IS_PLANAR = 0x00001000, + VPU_IS_SEMIPLANAR = 0x00002000, + VPU_IS_PACKED = 0x00004000, + + // Merged definitions using above flags: + VPU_PF_UNDEFINED = 0, + VPU_PF_YUV420_SEMIPLANAR = 0x00010000 | VPU_IS_SEMIPLANAR, + VPU_PF_YUV420_PLANAR = 0x00020000 | VPU_IS_PLANAR, + VPU_PF_UYVY = 0x00040000 | VPU_IS_PACKED, + VPU_PF_TILED_8BPP = 0x00080000 | VPU_IS_TILED | VPU_IS_SEMIPLANAR, + VPU_PF_TILED_10BPP = 0x00100000 | VPU_IS_TILED | VPU_IS_SEMIPLANAR | VPU_HAS_10BPP, +}; + +enum ARV_FRAME_TYPE { + ARV_8 = 0, + ARV_9, + ARV_10, +}; + +struct VPU_FMT_INFO_ARV { + u_int32 data_len; + u_int32 slice_num; + u_int32 *slice_offset; + u_int32 packlen; + enum ARV_FRAME_TYPE type; +}; + +struct vpu_v4l2_fmt { + char *name; + unsigned int fourcc; + unsigned int num_planes; + unsigned int vdec_std; + unsigned int disable; +}; + +struct vb2_data_req { + struct list_head list; + struct vb2_buffer *vb2_buf; + int id; + u_int32 status; + bool bfield; + bool queued; + u_int32 phy_addr[2]; //0 for luma, 1 for chroma + u_int32 data_offset[2]; //0 for luma, 1 for chroma + u32 seq_tag; +}; + +struct queue_data { + unsigned int width; + unsigned int height; + unsigned int stride; + unsigned int field; + unsigned int num_planes; + unsigned int sizeimage[2]; + unsigned int fourcc; + unsigned int vdec_std; + int buf_type; // v4l2_buf_type + bool vb2_q_inited; + struct vb2_queue vb2_q; // vb2 queue + struct list_head drv_q; // driver queue + struct semaphore drv_q_lock; + struct vb2_data_req vb2_reqs[VPU_MAX_BUFFER]; + enum QUEUE_TYPE type; + unsigned long qbuf_count; + unsigned long dqbuf_count; + unsigned long process_count; + bool enable; + struct vpu_ctx *ctx; +}; + +struct print_buf_desc { + u32 start_h_phy; + u32 start_h_vir; + u32 start_m; + u32 bytes; + u32 read; + u32 write; + char buffer[0]; +}; + +#ifdef CONFIG_IMX_SCU +struct vpu_imx_sc_msg_misc { + struct imx_sc_rpc_msg hdr; + u32 word; +} __packed; +#endif + +struct vpu_sc_chan { + struct vpu_dev *dev; + char name[20]; + struct mbox_client cl; + struct mbox_chan *ch; +}; + +struct vpu_ctx_work { + struct work_struct instance_work; + struct delayed_work delayed_instance_work; + int str_index; + struct vpu_dev *dev; +}; + +struct vpu_ctx; +struct vpu_dev { + struct device *generic_dev; + struct v4l2_device v4l2_dev; + struct video_device *pvpu_decoder_dev; + struct platform_device *plat_dev; + struct firmware *m0_pfw; + void *m0_p_fw_space_vir; + u_int32 m0_p_fw_space_phy; + u_int32 m0_boot_size; + void *m0_rpc_virt; + u_int32 m0_rpc_phy; + u_int32 m0_rpc_size; + struct mutex dev_mutex; + struct mutex cmd_mutex; + bool fw_is_ready; + bool firmware_started; + bool need_cleanup_firmware; + bool suspend; + struct completion start_cmp; + struct completion snap_done_cmp; + struct workqueue_struct *workqueue; + struct work_struct msg_work; + struct delayed_work delayed_msg_work; + unsigned long instance_mask; + unsigned long hang_mask; //this is used to deal with hang issue to reset firmware + struct clk *vpu_clk; + void __iomem *mu_base_virtaddr; + unsigned int vpu_mu_id; + int vpu_mu_init; + u_int32 plat_type; + + struct clk *clk_m0; + void __iomem *regs_base; + void __iomem *csr_base; + u_int32 cm_offset; + + struct shared_addr shared_mem; + struct vpu_ctx *ctx[VPU_MAX_NUM_STREAMS]; + struct vpu_ctx_work ctx_work[VPU_MAX_NUM_STREAMS]; + struct dentry *debugfs_root; + struct dentry *debugfs_dbglog; + struct dentry *debugfs_fwlog; + + struct print_buf_desc *print_buf; + u8 precheck_pattern[64]; + int precheck_next[64]; + int precheck_num; + char precheck_content[1024]; + + struct kfifo mu_msg_fifo; + void *mu_msg_buffer; + unsigned int mu_msg_buffer_size; + u_int32 vpu_irq; + + /* reserve for kernel version 5.4 or later */ + struct vpu_sc_chan sc_chan_tx0; + struct vpu_sc_chan sc_chan_tx1; + struct vpu_sc_chan sc_chan_rx; + struct device *pd_vpu; + struct device *pd_dec; + struct device *pd_mu; + struct device_link *pd_vpu_link; + struct device_link *pd_dec_link; + struct device_link *pd_mu_link; +}; + +struct vpu_statistic { + unsigned long cmd[VID_API_CMD_TS + 2]; + unsigned long event[VID_API_EVENT_DEC_CFG_INFO + 2]; + unsigned long current_cmd; + unsigned long current_event; + unsigned long skipped_frame_count; + struct timespec64 ts_cmd; + struct timespec64 ts_event; + atomic64_t total_dma_size; + atomic64_t total_alloc_size; +}; + +struct dma_buffer { + dma_addr_t dma_phy; + void *dma_virt; + u_int32 dma_size; +}; + +struct vpu_dec_cmd_request { + struct list_head list; + u32 request; + u32 response; + bool block; + u32 idx; + u32 num; + u32 data[VPU_DEC_CMD_DATA_MAX_NUM]; +}; + +struct vpu_dec_perf_time { + u_int64 open_time; + + u_int64 first_decoded_time; + u_int64 last_decoded_time; + u_int64 cur_decoded_interv; + u_int64 decoded_fps; + + u_int64 first_ready_time; + u_int64 last_ready_time; + u_int64 cur_ready_interv; + u_int64 ready_fps; +}; + +struct vpu_dec_perf_queue { + struct list_head list; + char str[VPU_MAX_STEP_STRING_LENGTH]; + u_int64 time; +}; + +struct vpu_ctx { + struct vpu_dev *dev; + struct v4l2_fh fh; + + struct vpu_statistic statistic; + struct device_attribute dev_attr_instance_command; + char command_name[64]; + struct device_attribute dev_attr_instance_event; + char event_name[64]; + struct device_attribute dev_attr_instance_buffer; + char buffer_name[64]; + struct device_attribute dev_attr_instance_flow; + char flow_name[64]; + struct device_attribute dev_attr_instance_perf; + char perf_name[64]; + struct v4l2_ctrl_handler ctrl_handler; + bool ctrl_inited; + struct list_head log_q; + + int str_index; + struct queue_data q_data[2]; + struct kfifo msg_fifo; + void *msg_buffer; + unsigned int msg_buffer_size; + struct mutex instance_mutex; + struct work_struct *instance_work; + struct delayed_work *delayed_instance_work; + struct workqueue_struct *instance_wq; + struct completion completion; + struct completion stop_cmp; + struct completion eos_cmp; + MediaIPFW_Video_SeqInfo seqinfo; + bool b_dis_reorder; + bool b_firstseq; + bool wait_rst_done; + bool wait_res_change_done; + bool seek_flag; + bool firmware_stopped; + bool firmware_finished; + bool eos_stop_received; + bool eos_stop_added; + bool ctx_released; + bool start_code_bypass; + STREAM_INPUT_MODE stream_input_mode; + bool hang_status; + bool fifo_low; + bool frame_decoded; + bool first_dump_data_flag; + bool first_data_flag; + u32 req_frame_count; + u32 req_mbi_count; + u32 req_dcp_count; + u32 mbi_count; + u32 mbi_size; + u32 dcp_count; + u32 dcp_size; + u32 mbi_index; + u32 dcp_index; + struct dma_buffer dpb_buffer; + struct dma_buffer dcp_buffer[MAX_DCP_NUM]; + struct dma_buffer mbi_buffer[MAX_MBI_NUM]; + struct dma_buffer stream_buffer; + struct dma_buffer udata_buffer; + enum ARV_FRAME_TYPE arv_type; + u32 beginning; + + struct file *crc_fp; + loff_t pos; + + int frm_dis_delay; + int frm_dec_delay; + int frm_total_num; + + long total_qbuf_bytes; + long total_write_bytes; + u32 extra_size; + s64 output_ts; + s64 capture_ts; + s64 ts_threshold; + u32 bs_l_threshold; + u32 bs_h_threshold; + + struct v4l2_fract fixed_frame_interval; + struct v4l2_fract frame_interval; + + struct list_head cmd_q; + struct vpu_dec_cmd_request *pending; + struct mutex cmd_lock; + + struct vpu_dec_perf_time perf_time; + int res_change_occu_count; + int res_change_send_count; + int res_change_done_count; + + struct list_head perf_q; + struct mutex perf_lock; + + struct mutex fw_flow_mutex; + + u8 colorspace; + u8 xfer_func; + u8 ycbcr_enc; + u8 quantization; +}; + +#define LVL_WARN (1 << 0) +#define LVL_EVENT (1 << 1) +#define LVL_INFO (1 << 2) +#define LVL_BIT_CMD (1 << 4) +#define LVL_BIT_EVT (1 << 5) +#define LVL_BIT_TS (1 << 6) +#define LVL_BIT_FRAME_BYTES (1 << 7) +#define LVL_BIT_WPTR (1 << 8) +#define LVL_BIT_PIC_ADDR (1 << 9) +#define LVL_BIT_BUFFER_STAT (1 << 10) +#define LVL_BIT_BUFFER_DESC (1 << 11) +#define LVL_BIT_FUNC (1 << 12) +#define LVL_BIT_FLOW (1 << 13) +#define LVL_BIT_FRAME_COUNT (1 << 14) + +#define vpu_err(fmt, arg...) pr_info("[VPU Decoder] " fmt, ## arg) + +#define vpu_dbg(level, fmt, arg...) \ + do { \ + if (vpu_dbg_level_decoder & (level)) \ + pr_info("[VPU Decoder] " fmt, ## arg); \ + } while (0) + +#define V4L2_NXP_BUF_FLAG_CODECCONFIG 0x00200000 +#define V4L2_NXP_BUF_FLAG_TIMESTAMP_INVALID 0x00400000 + +#define V4L2_NXP_BUF_MASK_FLAGS (V4L2_NXP_BUF_FLAG_CODECCONFIG | \ + V4L2_NXP_BUF_FLAG_TIMESTAMP_INVALID) + +#define VPU_DECODED_EVENT_PERF_MASK (1 << 0) +#define VPU_READY_EVENT_PERF_MASK (1 << 1) + +#define V4L2_NXP_FRAME_VERTICAL_ALIGN 512 +#define V4L2_NXP_FRAME_HORIZONTAL_ALIGN 512 + +#define VPU_IMX_DECODER_FUSE_OFFSET 14 + +pSTREAM_BUFFER_DESCRIPTOR_TYPE get_str_buffer_desc(struct vpu_ctx *ctx); +u_int32 got_free_space(u_int32 wptr, u_int32 rptr, u_int32 start, u_int32 end); +int copy_buffer_to_stream(struct vpu_ctx *ctx, void *buffer, uint32_t length); + +#endif |