xref: /openbmc/linux/drivers/media/platform/amphion/vpu_rpc.h (revision 4f2c0a4acffbec01079c28f839422e64ddeff004)
1  /* SPDX-License-Identifier: GPL-2.0 */
2  /*
3   * Copyright 2020-2021 NXP
4   */
5  
6  #ifndef _AMPHION_VPU_RPC_H
7  #define _AMPHION_VPU_RPC_H
8  
9  #include <media/videobuf2-core.h>
10  #include "vpu_codec.h"
11  
12  struct vpu_rpc_buffer_desc {
13  	u32 wptr;
14  	u32 rptr;
15  	u32 start;
16  	u32 end;
17  };
18  
19  struct vpu_shared_addr {
20  	void *iface;
21  	struct vpu_rpc_buffer_desc *cmd_desc;
22  	void *cmd_mem_vir;
23  	struct vpu_rpc_buffer_desc *msg_desc;
24  	void *msg_mem_vir;
25  
26  	unsigned long boot_addr;
27  	struct vpu_core *core;
28  	void *priv;
29  };
30  
31  struct vpu_rpc_event_header {
32  	u32 index;
33  	u32 id;
34  	u32 num;
35  };
36  
37  struct vpu_rpc_event {
38  	struct vpu_rpc_event_header hdr;
39  	u32 data[128];
40  };
41  
42  struct vpu_iface_ops {
43  	bool (*check_codec)(enum vpu_core_type type);
44  	bool (*check_fmt)(enum vpu_core_type type, u32 pixelfmt);
45  	u32 (*get_data_size)(void);
46  	int (*check_memory_region)(dma_addr_t base, dma_addr_t addr, u32 size);
47  	int (*boot_core)(struct vpu_core *core);
48  	int (*shutdown_core)(struct vpu_core *core);
49  	int (*restore_core)(struct vpu_core *core);
50  	int (*get_power_state)(struct vpu_core *core);
51  	int (*on_firmware_loaded)(struct vpu_core *core);
52  	void (*init_rpc)(struct vpu_shared_addr *shared,
53  			 struct vpu_buffer *rpc, dma_addr_t boot_addr);
54  	void (*set_log_buf)(struct vpu_shared_addr *shared,
55  			    struct vpu_buffer *log);
56  	void (*set_system_cfg)(struct vpu_shared_addr *shared,
57  			       u32 regs_base, void __iomem *regs, u32 index);
58  	void (*set_stream_cfg)(struct vpu_shared_addr *shared, u32 index);
59  	u32 (*get_version)(struct vpu_shared_addr *shared);
60  	u32 (*get_max_instance_count)(struct vpu_shared_addr *shared);
61  	int (*get_stream_buffer_size)(struct vpu_shared_addr *shared);
62  	int (*send_cmd_buf)(struct vpu_shared_addr *shared,
63  			    struct vpu_rpc_event *cmd);
64  	int (*receive_msg_buf)(struct vpu_shared_addr *shared,
65  			       struct vpu_rpc_event *msg);
66  	int (*pack_cmd)(struct vpu_rpc_event *pkt, u32 index, u32 id, void *data);
67  	int (*convert_msg_id)(u32 msg_id);
68  	int (*unpack_msg_data)(struct vpu_rpc_event *pkt, void *data);
69  	int (*input_frame)(struct vpu_shared_addr *shared,
70  			   struct vpu_inst *inst, struct vb2_buffer *vb);
71  	int (*config_memory_resource)(struct vpu_shared_addr *shared,
72  				      u32 instance,
73  				      u32 type,
74  				      u32 index,
75  				      struct vpu_buffer *buf);
76  	int (*config_stream_buffer)(struct vpu_shared_addr *shared,
77  				    u32 instance,
78  				    struct vpu_buffer *buf);
79  	int (*update_stream_buffer)(struct vpu_shared_addr *shared,
80  				    u32 instance, u32 ptr, bool write);
81  	int (*get_stream_buffer_desc)(struct vpu_shared_addr *shared,
82  				      u32 instance,
83  				      struct vpu_rpc_buffer_desc *desc);
84  	int (*set_encode_params)(struct vpu_shared_addr *shared,
85  				 u32 instance,
86  				 struct vpu_encode_params *params,
87  				 u32 update);
88  	int (*set_decode_params)(struct vpu_shared_addr *shared,
89  				 u32 instance,
90  				 struct vpu_decode_params *params,
91  				 u32 update);
92  	int (*add_scode)(struct vpu_shared_addr *shared,
93  			 u32 instance,
94  			 struct vpu_buffer *stream_buffer,
95  			 u32 pixelformat,
96  			 u32 scode_type);
97  	int (*pre_send_cmd)(struct vpu_shared_addr *shared, u32 instance);
98  	int (*post_send_cmd)(struct vpu_shared_addr *shared, u32 instance);
99  	int (*init_instance)(struct vpu_shared_addr *shared, u32 instance);
100  };
101  
102  enum {
103  	VPU_CORE_MEMORY_INVALID = 0,
104  	VPU_CORE_MEMORY_CACHED,
105  	VPU_CORE_MEMORY_UNCACHED
106  };
107  
108  struct vpu_rpc_region_t {
109  	dma_addr_t start;
110  	dma_addr_t end;
111  	dma_addr_t type;
112  };
113  
114  struct vpu_iface_ops *vpu_core_get_iface(struct vpu_core *core);
115  struct vpu_iface_ops *vpu_inst_get_iface(struct vpu_inst *inst);
116  int vpu_iface_check_memory_region(struct vpu_core *core, dma_addr_t addr, u32 size);
117  
vpu_iface_check_codec(struct vpu_core * core)118  static inline bool vpu_iface_check_codec(struct vpu_core *core)
119  {
120  	struct vpu_iface_ops *ops = vpu_core_get_iface(core);
121  
122  	if (ops && ops->check_codec)
123  		return ops->check_codec(core->type);
124  
125  	return true;
126  }
127  
vpu_iface_check_format(struct vpu_inst * inst,u32 pixelfmt)128  static inline bool vpu_iface_check_format(struct vpu_inst *inst, u32 pixelfmt)
129  {
130  	struct vpu_iface_ops *ops = vpu_inst_get_iface(inst);
131  
132  	if (ops && ops->check_fmt)
133  		return ops->check_fmt(inst->type, pixelfmt);
134  
135  	return true;
136  }
137  
vpu_iface_boot_core(struct vpu_core * core)138  static inline int vpu_iface_boot_core(struct vpu_core *core)
139  {
140  	struct vpu_iface_ops *ops = vpu_core_get_iface(core);
141  
142  	if (ops && ops->boot_core)
143  		return ops->boot_core(core);
144  	return 0;
145  }
146  
vpu_iface_get_power_state(struct vpu_core * core)147  static inline int vpu_iface_get_power_state(struct vpu_core *core)
148  {
149  	struct vpu_iface_ops *ops = vpu_core_get_iface(core);
150  
151  	if (ops && ops->get_power_state)
152  		return ops->get_power_state(core);
153  	return 1;
154  }
155  
vpu_iface_shutdown_core(struct vpu_core * core)156  static inline int vpu_iface_shutdown_core(struct vpu_core *core)
157  {
158  	struct vpu_iface_ops *ops = vpu_core_get_iface(core);
159  
160  	if (ops && ops->shutdown_core)
161  		return ops->shutdown_core(core);
162  	return 0;
163  }
164  
vpu_iface_restore_core(struct vpu_core * core)165  static inline int vpu_iface_restore_core(struct vpu_core *core)
166  {
167  	struct vpu_iface_ops *ops = vpu_core_get_iface(core);
168  
169  	if (ops && ops->restore_core)
170  		return ops->restore_core(core);
171  	return 0;
172  }
173  
vpu_iface_on_firmware_loaded(struct vpu_core * core)174  static inline int vpu_iface_on_firmware_loaded(struct vpu_core *core)
175  {
176  	struct vpu_iface_ops *ops = vpu_core_get_iface(core);
177  
178  	if (ops && ops->on_firmware_loaded)
179  		return ops->on_firmware_loaded(core);
180  
181  	return 0;
182  }
183  
vpu_iface_get_data_size(struct vpu_core * core)184  static inline u32 vpu_iface_get_data_size(struct vpu_core *core)
185  {
186  	struct vpu_iface_ops *ops = vpu_core_get_iface(core);
187  
188  	if (!ops || !ops->get_data_size)
189  		return 0;
190  
191  	return ops->get_data_size();
192  }
193  
vpu_iface_init(struct vpu_core * core,struct vpu_shared_addr * shared,struct vpu_buffer * rpc,dma_addr_t boot_addr)194  static inline int vpu_iface_init(struct vpu_core *core,
195  				 struct vpu_shared_addr *shared,
196  				 struct vpu_buffer *rpc,
197  				 dma_addr_t boot_addr)
198  {
199  	struct vpu_iface_ops *ops = vpu_core_get_iface(core);
200  
201  	if (!ops || !ops->init_rpc)
202  		return -EINVAL;
203  
204  	ops->init_rpc(shared, rpc, boot_addr);
205  	core->iface = shared;
206  	shared->core = core;
207  	if (rpc->bytesused > rpc->length)
208  		return -ENOSPC;
209  	return 0;
210  }
211  
vpu_iface_set_log_buf(struct vpu_core * core,struct vpu_buffer * log)212  static inline int vpu_iface_set_log_buf(struct vpu_core *core,
213  					struct vpu_buffer *log)
214  {
215  	struct vpu_iface_ops *ops = vpu_core_get_iface(core);
216  
217  	if (!ops)
218  		return -EINVAL;
219  
220  	if (ops->set_log_buf)
221  		ops->set_log_buf(core->iface, log);
222  
223  	return 0;
224  }
225  
vpu_iface_config_system(struct vpu_core * core,u32 regs_base,void __iomem * regs)226  static inline int vpu_iface_config_system(struct vpu_core *core, u32 regs_base, void __iomem *regs)
227  {
228  	struct vpu_iface_ops *ops = vpu_core_get_iface(core);
229  
230  	if (!ops)
231  		return -EINVAL;
232  	if (ops->set_system_cfg)
233  		ops->set_system_cfg(core->iface, regs_base, regs, core->id);
234  
235  	return 0;
236  }
237  
vpu_iface_get_stream_buffer_size(struct vpu_core * core)238  static inline int vpu_iface_get_stream_buffer_size(struct vpu_core *core)
239  {
240  	struct vpu_iface_ops *ops = vpu_core_get_iface(core);
241  
242  	if (!ops || !ops->get_stream_buffer_size)
243  		return 0;
244  
245  	return ops->get_stream_buffer_size(core->iface);
246  }
247  
vpu_iface_config_stream(struct vpu_inst * inst)248  static inline int vpu_iface_config_stream(struct vpu_inst *inst)
249  {
250  	struct vpu_iface_ops *ops = vpu_core_get_iface(inst->core);
251  
252  	if (!ops || inst->id < 0)
253  		return -EINVAL;
254  	if (ops->set_stream_cfg)
255  		ops->set_stream_cfg(inst->core->iface, inst->id);
256  	return 0;
257  }
258  
vpu_iface_send_cmd(struct vpu_core * core,struct vpu_rpc_event * cmd)259  static inline int vpu_iface_send_cmd(struct vpu_core *core, struct vpu_rpc_event *cmd)
260  {
261  	struct vpu_iface_ops *ops = vpu_core_get_iface(core);
262  
263  	if (!ops || !ops->send_cmd_buf)
264  		return -EINVAL;
265  
266  	return ops->send_cmd_buf(core->iface, cmd);
267  }
268  
vpu_iface_receive_msg(struct vpu_core * core,struct vpu_rpc_event * msg)269  static inline int vpu_iface_receive_msg(struct vpu_core *core, struct vpu_rpc_event *msg)
270  {
271  	struct vpu_iface_ops *ops = vpu_core_get_iface(core);
272  
273  	if (!ops || !ops->receive_msg_buf)
274  		return -EINVAL;
275  
276  	return ops->receive_msg_buf(core->iface, msg);
277  }
278  
vpu_iface_pack_cmd(struct vpu_core * core,struct vpu_rpc_event * pkt,u32 index,u32 id,void * data)279  static inline int vpu_iface_pack_cmd(struct vpu_core *core,
280  				     struct vpu_rpc_event *pkt,
281  				     u32 index, u32 id, void *data)
282  {
283  	struct vpu_iface_ops *ops = vpu_core_get_iface(core);
284  
285  	if (!ops || !ops->pack_cmd)
286  		return -EINVAL;
287  	return ops->pack_cmd(pkt, index, id, data);
288  }
289  
vpu_iface_convert_msg_id(struct vpu_core * core,u32 msg_id)290  static inline int vpu_iface_convert_msg_id(struct vpu_core *core, u32 msg_id)
291  {
292  	struct vpu_iface_ops *ops = vpu_core_get_iface(core);
293  
294  	if (!ops || !ops->convert_msg_id)
295  		return -EINVAL;
296  
297  	return ops->convert_msg_id(msg_id);
298  }
299  
vpu_iface_unpack_msg_data(struct vpu_core * core,struct vpu_rpc_event * pkt,void * data)300  static inline int vpu_iface_unpack_msg_data(struct vpu_core *core,
301  					    struct vpu_rpc_event *pkt, void *data)
302  {
303  	struct vpu_iface_ops *ops = vpu_core_get_iface(core);
304  
305  	if (!ops || !ops->unpack_msg_data)
306  		return -EINVAL;
307  
308  	return ops->unpack_msg_data(pkt, data);
309  }
310  
vpu_iface_input_frame(struct vpu_inst * inst,struct vb2_buffer * vb)311  static inline int vpu_iface_input_frame(struct vpu_inst *inst,
312  					struct vb2_buffer *vb)
313  {
314  	struct vpu_iface_ops *ops = vpu_core_get_iface(inst->core);
315  	int ret;
316  
317  	if (!ops || !ops->input_frame)
318  		return -EINVAL;
319  
320  	ret = ops->input_frame(inst->core->iface, inst, vb);
321  	if (ret < 0)
322  		return ret;
323  	inst->total_input_count++;
324  	return ret;
325  }
326  
vpu_iface_config_memory_resource(struct vpu_inst * inst,u32 type,u32 index,struct vpu_buffer * buf)327  static inline int vpu_iface_config_memory_resource(struct vpu_inst *inst,
328  						   u32 type,
329  						   u32 index,
330  						   struct vpu_buffer *buf)
331  {
332  	struct vpu_iface_ops *ops = vpu_core_get_iface(inst->core);
333  
334  	if (!ops || !ops->config_memory_resource || inst->id < 0)
335  		return -EINVAL;
336  
337  	return ops->config_memory_resource(inst->core->iface,
338  					inst->id,
339  					type, index, buf);
340  }
341  
vpu_iface_config_stream_buffer(struct vpu_inst * inst,struct vpu_buffer * buf)342  static inline int vpu_iface_config_stream_buffer(struct vpu_inst *inst,
343  						 struct vpu_buffer *buf)
344  {
345  	struct vpu_iface_ops *ops = vpu_core_get_iface(inst->core);
346  
347  	if (!ops || !ops->config_stream_buffer || inst->id < 0)
348  		return -EINVAL;
349  
350  	if ((buf->phys % 4) || (buf->length % 4))
351  		return -EINVAL;
352  	if (buf->phys + buf->length > (u64)UINT_MAX)
353  		return -EINVAL;
354  
355  	return ops->config_stream_buffer(inst->core->iface, inst->id, buf);
356  }
357  
vpu_iface_update_stream_buffer(struct vpu_inst * inst,u32 ptr,bool write)358  static inline int vpu_iface_update_stream_buffer(struct vpu_inst *inst,
359  						 u32 ptr, bool write)
360  {
361  	struct vpu_iface_ops *ops = vpu_core_get_iface(inst->core);
362  
363  	if (!ops || !ops->update_stream_buffer || inst->id < 0)
364  		return -EINVAL;
365  
366  	return ops->update_stream_buffer(inst->core->iface, inst->id, ptr, write);
367  }
368  
vpu_iface_get_stream_buffer_desc(struct vpu_inst * inst,struct vpu_rpc_buffer_desc * desc)369  static inline int vpu_iface_get_stream_buffer_desc(struct vpu_inst *inst,
370  						   struct vpu_rpc_buffer_desc *desc)
371  {
372  	struct vpu_iface_ops *ops = vpu_core_get_iface(inst->core);
373  
374  	if (!ops || !ops->get_stream_buffer_desc || inst->id < 0)
375  		return -EINVAL;
376  
377  	if (!desc)
378  		return 0;
379  
380  	return ops->get_stream_buffer_desc(inst->core->iface, inst->id, desc);
381  }
382  
vpu_iface_get_version(struct vpu_core * core)383  static inline u32 vpu_iface_get_version(struct vpu_core *core)
384  {
385  	struct vpu_iface_ops *ops = vpu_core_get_iface(core);
386  
387  	if (!ops || !ops->get_version)
388  		return 0;
389  
390  	return ops->get_version(core->iface);
391  }
392  
vpu_iface_get_max_instance_count(struct vpu_core * core)393  static inline u32 vpu_iface_get_max_instance_count(struct vpu_core *core)
394  {
395  	struct vpu_iface_ops *ops = vpu_core_get_iface(core);
396  
397  	if (!ops || !ops->get_max_instance_count)
398  		return 0;
399  
400  	return ops->get_max_instance_count(core->iface);
401  }
402  
vpu_iface_set_encode_params(struct vpu_inst * inst,struct vpu_encode_params * params,u32 update)403  static inline int vpu_iface_set_encode_params(struct vpu_inst *inst,
404  					      struct vpu_encode_params *params, u32 update)
405  {
406  	struct vpu_iface_ops *ops = vpu_core_get_iface(inst->core);
407  
408  	if (!ops || !ops->set_encode_params || inst->id < 0)
409  		return -EINVAL;
410  
411  	return ops->set_encode_params(inst->core->iface, inst->id, params, update);
412  }
413  
vpu_iface_set_decode_params(struct vpu_inst * inst,struct vpu_decode_params * params,u32 update)414  static inline int vpu_iface_set_decode_params(struct vpu_inst *inst,
415  					      struct vpu_decode_params *params, u32 update)
416  {
417  	struct vpu_iface_ops *ops = vpu_core_get_iface(inst->core);
418  
419  	if (!ops || !ops->set_decode_params  || inst->id < 0)
420  		return -EINVAL;
421  
422  	return ops->set_decode_params(inst->core->iface, inst->id, params, update);
423  }
424  
vpu_iface_add_scode(struct vpu_inst * inst,u32 scode_type)425  static inline int vpu_iface_add_scode(struct vpu_inst *inst, u32 scode_type)
426  {
427  	struct vpu_iface_ops *ops = vpu_core_get_iface(inst->core);
428  
429  	if (!ops || !ops->add_scode  || inst->id < 0)
430  		return -EINVAL;
431  
432  	return ops->add_scode(inst->core->iface, inst->id,
433  				&inst->stream_buffer,
434  				inst->out_format.pixfmt,
435  				scode_type);
436  }
437  
vpu_iface_pre_send_cmd(struct vpu_inst * inst)438  static inline int vpu_iface_pre_send_cmd(struct vpu_inst *inst)
439  {
440  	struct vpu_iface_ops *ops = vpu_core_get_iface(inst->core);
441  
442  	if (ops && ops->pre_send_cmd && inst->id >= 0)
443  		return ops->pre_send_cmd(inst->core->iface, inst->id);
444  	return 0;
445  }
446  
vpu_iface_post_send_cmd(struct vpu_inst * inst)447  static inline int vpu_iface_post_send_cmd(struct vpu_inst *inst)
448  {
449  	struct vpu_iface_ops *ops = vpu_core_get_iface(inst->core);
450  
451  	if (ops && ops->post_send_cmd && inst->id >= 0)
452  		return ops->post_send_cmd(inst->core->iface, inst->id);
453  	return 0;
454  }
455  
vpu_iface_init_instance(struct vpu_inst * inst)456  static inline int vpu_iface_init_instance(struct vpu_inst *inst)
457  {
458  	struct vpu_iface_ops *ops = vpu_core_get_iface(inst->core);
459  
460  	if (ops && ops->init_instance && inst->id >= 0)
461  		return ops->init_instance(inst->core->iface, inst->id);
462  
463  	return 0;
464  }
465  
466  #endif
467