xref: /linux/drivers/media/platform/amphion/vpu.h (revision b50a64fc54af5bacb2821c344611947ff4bdc0d2)
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