1*b50a64fcSMing Qian /* SPDX-License-Identifier: GPL-2.0 */ 2*b50a64fcSMing Qian /* 3*b50a64fcSMing Qian * Copyright 2020-2021 NXP 4*b50a64fcSMing Qian */ 5*b50a64fcSMing Qian 6*b50a64fcSMing Qian #ifndef _AMPHION_VPU_H 7*b50a64fcSMing Qian #define _AMPHION_VPU_H 8*b50a64fcSMing Qian 9*b50a64fcSMing Qian #include <media/v4l2-device.h> 10*b50a64fcSMing Qian #include <media/v4l2-ctrls.h> 11*b50a64fcSMing Qian #include <media/v4l2-mem2mem.h> 12*b50a64fcSMing Qian #include <linux/mailbox_client.h> 13*b50a64fcSMing Qian #include <linux/mailbox_controller.h> 14*b50a64fcSMing Qian #include <linux/kfifo.h> 15*b50a64fcSMing Qian 16*b50a64fcSMing Qian #define VPU_TIMEOUT msecs_to_jiffies(1000) 17*b50a64fcSMing Qian #define VPU_INST_NULL_ID (-1L) 18*b50a64fcSMing Qian #define VPU_MSG_BUFFER_SIZE (8192) 19*b50a64fcSMing Qian 20*b50a64fcSMing Qian enum imx_plat_type { 21*b50a64fcSMing Qian IMX8QXP = 0, 22*b50a64fcSMing Qian IMX8QM = 1, 23*b50a64fcSMing Qian IMX8DM, 24*b50a64fcSMing Qian IMX8DX, 25*b50a64fcSMing Qian PLAT_TYPE_RESERVED 26*b50a64fcSMing Qian }; 27*b50a64fcSMing Qian 28*b50a64fcSMing Qian enum vpu_core_type { 29*b50a64fcSMing Qian VPU_CORE_TYPE_ENC = 0, 30*b50a64fcSMing Qian VPU_CORE_TYPE_DEC = 0x10, 31*b50a64fcSMing Qian }; 32*b50a64fcSMing Qian 33*b50a64fcSMing Qian struct vpu_dev; 34*b50a64fcSMing Qian struct vpu_resources { 35*b50a64fcSMing Qian enum imx_plat_type plat_type; 36*b50a64fcSMing Qian u32 mreg_base; 37*b50a64fcSMing Qian int (*setup)(struct vpu_dev *vpu); 38*b50a64fcSMing Qian int (*setup_encoder)(struct vpu_dev *vpu); 39*b50a64fcSMing Qian int (*setup_decoder)(struct vpu_dev *vpu); 40*b50a64fcSMing Qian int (*reset)(struct vpu_dev *vpu); 41*b50a64fcSMing Qian }; 42*b50a64fcSMing Qian 43*b50a64fcSMing Qian struct vpu_buffer { 44*b50a64fcSMing Qian void *virt; 45*b50a64fcSMing Qian dma_addr_t phys; 46*b50a64fcSMing Qian u32 length; 47*b50a64fcSMing Qian u32 bytesused; 48*b50a64fcSMing Qian struct device *dev; 49*b50a64fcSMing Qian }; 50*b50a64fcSMing Qian 51*b50a64fcSMing Qian struct vpu_func { 52*b50a64fcSMing Qian struct video_device *vfd; 53*b50a64fcSMing Qian struct v4l2_m2m_dev *m2m_dev; 54*b50a64fcSMing Qian enum vpu_core_type type; 55*b50a64fcSMing Qian int function; 56*b50a64fcSMing Qian }; 57*b50a64fcSMing Qian 58*b50a64fcSMing Qian struct vpu_dev { 59*b50a64fcSMing Qian void __iomem *base; 60*b50a64fcSMing Qian struct platform_device *pdev; 61*b50a64fcSMing Qian struct device *dev; 62*b50a64fcSMing Qian struct mutex lock; /* protect vpu device */ 63*b50a64fcSMing Qian const struct vpu_resources *res; 64*b50a64fcSMing Qian struct list_head cores; 65*b50a64fcSMing Qian 66*b50a64fcSMing Qian struct v4l2_device v4l2_dev; 67*b50a64fcSMing Qian struct vpu_func encoder; 68*b50a64fcSMing Qian struct vpu_func decoder; 69*b50a64fcSMing Qian struct media_device mdev; 70*b50a64fcSMing Qian 71*b50a64fcSMing Qian struct delayed_work watchdog_work; 72*b50a64fcSMing Qian void (*get_vpu)(struct vpu_dev *vpu); 73*b50a64fcSMing Qian void (*put_vpu)(struct vpu_dev *vpu); 74*b50a64fcSMing Qian void (*get_enc)(struct vpu_dev *vpu); 75*b50a64fcSMing Qian void (*put_enc)(struct vpu_dev *vpu); 76*b50a64fcSMing Qian void (*get_dec)(struct vpu_dev *vpu); 77*b50a64fcSMing Qian void (*put_dec)(struct vpu_dev *vpu); 78*b50a64fcSMing Qian atomic_t ref_vpu; 79*b50a64fcSMing Qian atomic_t ref_enc; 80*b50a64fcSMing Qian atomic_t ref_dec; 81*b50a64fcSMing Qian 82*b50a64fcSMing Qian struct dentry *debugfs; 83*b50a64fcSMing Qian }; 84*b50a64fcSMing Qian 85*b50a64fcSMing Qian struct vpu_format { 86*b50a64fcSMing Qian u32 pixfmt; 87*b50a64fcSMing Qian unsigned int num_planes; 88*b50a64fcSMing Qian u32 type; 89*b50a64fcSMing Qian u32 flags; 90*b50a64fcSMing Qian u32 width; 91*b50a64fcSMing Qian u32 height; 92*b50a64fcSMing Qian u32 sizeimage[VIDEO_MAX_PLANES]; 93*b50a64fcSMing Qian u32 bytesperline[VIDEO_MAX_PLANES]; 94*b50a64fcSMing Qian u32 field; 95*b50a64fcSMing Qian }; 96*b50a64fcSMing Qian 97*b50a64fcSMing Qian struct vpu_core_resources { 98*b50a64fcSMing Qian enum vpu_core_type type; 99*b50a64fcSMing Qian const char *fwname; 100*b50a64fcSMing Qian u32 stride; 101*b50a64fcSMing Qian u32 max_width; 102*b50a64fcSMing Qian u32 min_width; 103*b50a64fcSMing Qian u32 step_width; 104*b50a64fcSMing Qian u32 max_height; 105*b50a64fcSMing Qian u32 min_height; 106*b50a64fcSMing Qian u32 step_height; 107*b50a64fcSMing Qian u32 rpc_size; 108*b50a64fcSMing Qian u32 fwlog_size; 109*b50a64fcSMing Qian u32 act_size; 110*b50a64fcSMing Qian }; 111*b50a64fcSMing Qian 112*b50a64fcSMing Qian struct vpu_mbox { 113*b50a64fcSMing Qian char name[20]; 114*b50a64fcSMing Qian struct mbox_client cl; 115*b50a64fcSMing Qian struct mbox_chan *ch; 116*b50a64fcSMing Qian bool block; 117*b50a64fcSMing Qian }; 118*b50a64fcSMing Qian 119*b50a64fcSMing Qian enum vpu_core_state { 120*b50a64fcSMing Qian VPU_CORE_DEINIT = 0, 121*b50a64fcSMing Qian VPU_CORE_ACTIVE, 122*b50a64fcSMing Qian VPU_CORE_SNAPSHOT, 123*b50a64fcSMing Qian VPU_CORE_HANG 124*b50a64fcSMing Qian }; 125*b50a64fcSMing Qian 126*b50a64fcSMing Qian struct vpu_core { 127*b50a64fcSMing Qian void __iomem *base; 128*b50a64fcSMing Qian struct platform_device *pdev; 129*b50a64fcSMing Qian struct device *dev; 130*b50a64fcSMing Qian struct device *parent; 131*b50a64fcSMing Qian struct device *pd; 132*b50a64fcSMing Qian struct device_link *pd_link; 133*b50a64fcSMing Qian struct mutex lock; /* protect vpu core */ 134*b50a64fcSMing Qian struct mutex cmd_lock; /* Lock vpu command */ 135*b50a64fcSMing Qian struct list_head list; 136*b50a64fcSMing Qian enum vpu_core_type type; 137*b50a64fcSMing Qian int id; 138*b50a64fcSMing Qian const struct vpu_core_resources *res; 139*b50a64fcSMing Qian unsigned long instance_mask; 140*b50a64fcSMing Qian u32 supported_instance_count; 141*b50a64fcSMing Qian unsigned long hang_mask; 142*b50a64fcSMing Qian u32 request_count; 143*b50a64fcSMing Qian struct list_head instances; 144*b50a64fcSMing Qian enum vpu_core_state state; 145*b50a64fcSMing Qian u32 fw_version; 146*b50a64fcSMing Qian 147*b50a64fcSMing Qian struct vpu_buffer fw; 148*b50a64fcSMing Qian struct vpu_buffer rpc; 149*b50a64fcSMing Qian struct vpu_buffer log; 150*b50a64fcSMing Qian struct vpu_buffer act; 151*b50a64fcSMing Qian 152*b50a64fcSMing Qian struct vpu_mbox tx_type; 153*b50a64fcSMing Qian struct vpu_mbox tx_data; 154*b50a64fcSMing Qian struct vpu_mbox rx; 155*b50a64fcSMing Qian unsigned long cmd_seq; 156*b50a64fcSMing Qian 157*b50a64fcSMing Qian wait_queue_head_t ack_wq; 158*b50a64fcSMing Qian struct completion cmp; 159*b50a64fcSMing Qian struct workqueue_struct *workqueue; 160*b50a64fcSMing Qian struct work_struct msg_work; 161*b50a64fcSMing Qian struct delayed_work msg_delayed_work; 162*b50a64fcSMing Qian struct kfifo msg_fifo; 163*b50a64fcSMing Qian void *msg_buffer; 164*b50a64fcSMing Qian unsigned int msg_buffer_size; 165*b50a64fcSMing Qian 166*b50a64fcSMing Qian struct vpu_dev *vpu; 167*b50a64fcSMing Qian void *iface; 168*b50a64fcSMing Qian 169*b50a64fcSMing Qian struct dentry *debugfs; 170*b50a64fcSMing Qian struct dentry *debugfs_fwlog; 171*b50a64fcSMing Qian }; 172*b50a64fcSMing Qian 173*b50a64fcSMing Qian enum vpu_codec_state { 174*b50a64fcSMing Qian VPU_CODEC_STATE_DEINIT = 1, 175*b50a64fcSMing Qian VPU_CODEC_STATE_CONFIGURED, 176*b50a64fcSMing Qian VPU_CODEC_STATE_START, 177*b50a64fcSMing Qian VPU_CODEC_STATE_STARTED, 178*b50a64fcSMing Qian VPU_CODEC_STATE_ACTIVE, 179*b50a64fcSMing Qian VPU_CODEC_STATE_SEEK, 180*b50a64fcSMing Qian VPU_CODEC_STATE_STOP, 181*b50a64fcSMing Qian VPU_CODEC_STATE_DRAIN, 182*b50a64fcSMing Qian VPU_CODEC_STATE_DYAMIC_RESOLUTION_CHANGE, 183*b50a64fcSMing Qian }; 184*b50a64fcSMing Qian 185*b50a64fcSMing Qian struct vpu_frame_info { 186*b50a64fcSMing Qian u32 type; 187*b50a64fcSMing Qian u32 id; 188*b50a64fcSMing Qian u32 sequence; 189*b50a64fcSMing Qian u32 luma; 190*b50a64fcSMing Qian u32 chroma_u; 191*b50a64fcSMing Qian u32 chroma_v; 192*b50a64fcSMing Qian u32 data_offset; 193*b50a64fcSMing Qian u32 flags; 194*b50a64fcSMing Qian u32 skipped; 195*b50a64fcSMing Qian s64 timestamp; 196*b50a64fcSMing Qian }; 197*b50a64fcSMing Qian 198*b50a64fcSMing Qian struct vpu_inst; 199*b50a64fcSMing Qian struct vpu_inst_ops { 200*b50a64fcSMing Qian int (*ctrl_init)(struct vpu_inst *inst); 201*b50a64fcSMing Qian int (*start)(struct vpu_inst *inst, u32 type); 202*b50a64fcSMing Qian int (*stop)(struct vpu_inst *inst, u32 type); 203*b50a64fcSMing Qian int (*abort)(struct vpu_inst *inst); 204*b50a64fcSMing Qian bool (*check_ready)(struct vpu_inst *inst, unsigned int type); 205*b50a64fcSMing Qian void (*buf_done)(struct vpu_inst *inst, struct vpu_frame_info *frame); 206*b50a64fcSMing Qian void (*event_notify)(struct vpu_inst *inst, u32 event, void *data); 207*b50a64fcSMing Qian void (*release)(struct vpu_inst *inst); 208*b50a64fcSMing Qian void (*cleanup)(struct vpu_inst *inst); 209*b50a64fcSMing Qian void (*mem_request)(struct vpu_inst *inst, 210*b50a64fcSMing Qian u32 enc_frame_size, 211*b50a64fcSMing Qian u32 enc_frame_num, 212*b50a64fcSMing Qian u32 ref_frame_size, 213*b50a64fcSMing Qian u32 ref_frame_num, 214*b50a64fcSMing Qian u32 act_frame_size, 215*b50a64fcSMing Qian u32 act_frame_num); 216*b50a64fcSMing Qian void (*input_done)(struct vpu_inst *inst); 217*b50a64fcSMing Qian void (*stop_done)(struct vpu_inst *inst); 218*b50a64fcSMing Qian int (*process_output)(struct vpu_inst *inst, struct vb2_buffer *vb); 219*b50a64fcSMing Qian int (*process_capture)(struct vpu_inst *inst, struct vb2_buffer *vb); 220*b50a64fcSMing Qian int (*get_one_frame)(struct vpu_inst *inst, void *info); 221*b50a64fcSMing Qian void (*on_queue_empty)(struct vpu_inst *inst, u32 type); 222*b50a64fcSMing Qian int (*get_debug_info)(struct vpu_inst *inst, char *str, u32 size, u32 i); 223*b50a64fcSMing Qian void (*wait_prepare)(struct vpu_inst *inst); 224*b50a64fcSMing Qian void (*wait_finish)(struct vpu_inst *inst); 225*b50a64fcSMing Qian }; 226*b50a64fcSMing Qian 227*b50a64fcSMing Qian struct vpu_inst { 228*b50a64fcSMing Qian struct list_head list; 229*b50a64fcSMing Qian struct mutex lock; /* v4l2 and videobuf2 lock */ 230*b50a64fcSMing Qian struct vpu_dev *vpu; 231*b50a64fcSMing Qian struct vpu_core *core; 232*b50a64fcSMing Qian struct device *dev; 233*b50a64fcSMing Qian int id; 234*b50a64fcSMing Qian 235*b50a64fcSMing Qian struct v4l2_fh fh; 236*b50a64fcSMing Qian struct v4l2_ctrl_handler ctrl_handler; 237*b50a64fcSMing Qian atomic_t ref_count; 238*b50a64fcSMing Qian int (*release)(struct vpu_inst *inst); 239*b50a64fcSMing Qian 240*b50a64fcSMing Qian enum vpu_codec_state state; 241*b50a64fcSMing Qian enum vpu_core_type type; 242*b50a64fcSMing Qian 243*b50a64fcSMing Qian struct workqueue_struct *workqueue; 244*b50a64fcSMing Qian struct work_struct msg_work; 245*b50a64fcSMing Qian struct kfifo msg_fifo; 246*b50a64fcSMing Qian u8 msg_buffer[VPU_MSG_BUFFER_SIZE]; 247*b50a64fcSMing Qian 248*b50a64fcSMing Qian struct vpu_buffer stream_buffer; 249*b50a64fcSMing Qian bool use_stream_buffer; 250*b50a64fcSMing Qian struct vpu_buffer act; 251*b50a64fcSMing Qian 252*b50a64fcSMing Qian struct list_head cmd_q; 253*b50a64fcSMing Qian void *pending; 254*b50a64fcSMing Qian 255*b50a64fcSMing Qian struct vpu_inst_ops *ops; 256*b50a64fcSMing Qian const struct vpu_format *formats; 257*b50a64fcSMing Qian struct vpu_format out_format; 258*b50a64fcSMing Qian struct vpu_format cap_format; 259*b50a64fcSMing Qian u32 min_buffer_cap; 260*b50a64fcSMing Qian u32 min_buffer_out; 261*b50a64fcSMing Qian 262*b50a64fcSMing Qian struct v4l2_rect crop; 263*b50a64fcSMing Qian u32 colorspace; 264*b50a64fcSMing Qian u8 ycbcr_enc; 265*b50a64fcSMing Qian u8 quantization; 266*b50a64fcSMing Qian u8 xfer_func; 267*b50a64fcSMing Qian u32 sequence; 268*b50a64fcSMing Qian u32 extra_size; 269*b50a64fcSMing Qian 270*b50a64fcSMing Qian u32 flows[16]; 271*b50a64fcSMing Qian u32 flow_idx; 272*b50a64fcSMing Qian 273*b50a64fcSMing Qian pid_t pid; 274*b50a64fcSMing Qian pid_t tgid; 275*b50a64fcSMing Qian struct dentry *debugfs; 276*b50a64fcSMing Qian 277*b50a64fcSMing Qian void *priv; 278*b50a64fcSMing Qian }; 279*b50a64fcSMing Qian 280*b50a64fcSMing Qian #define call_vop(inst, op, args...) \ 281*b50a64fcSMing Qian ((inst)->ops->op ? (inst)->ops->op(inst, ##args) : 0) \ 282*b50a64fcSMing Qian 283*b50a64fcSMing Qian #define call_void_vop(inst, op, args...) \ 284*b50a64fcSMing Qian do { \ 285*b50a64fcSMing Qian if ((inst)->ops->op) \ 286*b50a64fcSMing Qian (inst)->ops->op(inst, ##args); \ 287*b50a64fcSMing Qian } while (0) 288*b50a64fcSMing Qian 289*b50a64fcSMing Qian enum { 290*b50a64fcSMing Qian VPU_BUF_STATE_IDLE = 0, 291*b50a64fcSMing Qian VPU_BUF_STATE_INUSE, 292*b50a64fcSMing Qian VPU_BUF_STATE_DECODED, 293*b50a64fcSMing Qian VPU_BUF_STATE_READY, 294*b50a64fcSMing Qian VPU_BUF_STATE_SKIP, 295*b50a64fcSMing Qian VPU_BUF_STATE_ERROR 296*b50a64fcSMing Qian }; 297*b50a64fcSMing Qian 298*b50a64fcSMing Qian struct vpu_vb2_buffer { 299*b50a64fcSMing Qian struct v4l2_m2m_buffer m2m_buf; 300*b50a64fcSMing Qian dma_addr_t luma; 301*b50a64fcSMing Qian dma_addr_t chroma_u; 302*b50a64fcSMing Qian dma_addr_t chroma_v; 303*b50a64fcSMing Qian unsigned int state; 304*b50a64fcSMing Qian u32 tag; 305*b50a64fcSMing Qian }; 306*b50a64fcSMing Qian 307*b50a64fcSMing Qian void vpu_writel(struct vpu_dev *vpu, u32 reg, u32 val); 308*b50a64fcSMing Qian u32 vpu_readl(struct vpu_dev *vpu, u32 reg); 309*b50a64fcSMing Qian 310*b50a64fcSMing Qian static inline struct vpu_vb2_buffer *to_vpu_vb2_buffer(struct vb2_v4l2_buffer *vbuf) 311*b50a64fcSMing Qian { 312*b50a64fcSMing Qian struct v4l2_m2m_buffer *m2m_buf = container_of(vbuf, struct v4l2_m2m_buffer, vb); 313*b50a64fcSMing Qian 314*b50a64fcSMing Qian return container_of(m2m_buf, struct vpu_vb2_buffer, m2m_buf); 315*b50a64fcSMing Qian } 316*b50a64fcSMing Qian 317*b50a64fcSMing Qian static inline const char *vpu_core_type_desc(enum vpu_core_type type) 318*b50a64fcSMing Qian { 319*b50a64fcSMing Qian return type == VPU_CORE_TYPE_ENC ? "encoder" : "decoder"; 320*b50a64fcSMing Qian } 321*b50a64fcSMing Qian 322*b50a64fcSMing Qian static inline struct vpu_inst *to_inst(struct file *filp) 323*b50a64fcSMing Qian { 324*b50a64fcSMing Qian return container_of(filp->private_data, struct vpu_inst, fh); 325*b50a64fcSMing Qian } 326*b50a64fcSMing Qian 327*b50a64fcSMing Qian #define ctrl_to_inst(ctrl) \ 328*b50a64fcSMing Qian container_of((ctrl)->handler, struct vpu_inst, ctrl_handler) 329*b50a64fcSMing Qian 330*b50a64fcSMing Qian const struct v4l2_ioctl_ops *venc_get_ioctl_ops(void); 331*b50a64fcSMing Qian const struct v4l2_file_operations *venc_get_fops(void); 332*b50a64fcSMing Qian const struct v4l2_ioctl_ops *vdec_get_ioctl_ops(void); 333*b50a64fcSMing Qian const struct v4l2_file_operations *vdec_get_fops(void); 334*b50a64fcSMing Qian 335*b50a64fcSMing Qian int vpu_add_func(struct vpu_dev *vpu, struct vpu_func *func); 336*b50a64fcSMing Qian void vpu_remove_func(struct vpu_func *func); 337*b50a64fcSMing Qian 338*b50a64fcSMing Qian struct vpu_inst *vpu_inst_get(struct vpu_inst *inst); 339*b50a64fcSMing Qian void vpu_inst_put(struct vpu_inst *inst); 340*b50a64fcSMing Qian struct vpu_core *vpu_request_core(struct vpu_dev *vpu, enum vpu_core_type type); 341*b50a64fcSMing Qian void vpu_release_core(struct vpu_core *core); 342*b50a64fcSMing Qian int vpu_inst_register(struct vpu_inst *inst); 343*b50a64fcSMing Qian int vpu_inst_unregister(struct vpu_inst *inst); 344*b50a64fcSMing Qian const struct vpu_core_resources *vpu_get_resource(struct vpu_inst *inst); 345*b50a64fcSMing Qian 346*b50a64fcSMing Qian int vpu_inst_create_dbgfs_file(struct vpu_inst *inst); 347*b50a64fcSMing Qian int vpu_inst_remove_dbgfs_file(struct vpu_inst *inst); 348*b50a64fcSMing Qian int vpu_core_create_dbgfs_file(struct vpu_core *core); 349*b50a64fcSMing Qian int vpu_core_remove_dbgfs_file(struct vpu_core *core); 350*b50a64fcSMing Qian void vpu_inst_record_flow(struct vpu_inst *inst, u32 flow); 351*b50a64fcSMing Qian 352*b50a64fcSMing Qian int vpu_core_driver_init(void); 353*b50a64fcSMing Qian void vpu_core_driver_exit(void); 354*b50a64fcSMing Qian 355*b50a64fcSMing Qian extern bool debug; 356*b50a64fcSMing Qian #define vpu_trace(dev, fmt, arg...) \ 357*b50a64fcSMing Qian do { \ 358*b50a64fcSMing Qian if (debug) \ 359*b50a64fcSMing Qian dev_info(dev, "%s: " fmt, __func__, ## arg); \ 360*b50a64fcSMing Qian } while (0) 361*b50a64fcSMing Qian 362*b50a64fcSMing Qian #endif 363