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