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