diff options
Diffstat (limited to 'gxp-mailbox-manager.h')
-rw-r--r-- | gxp-mailbox-manager.h | 137 |
1 files changed, 137 insertions, 0 deletions
diff --git a/gxp-mailbox-manager.h b/gxp-mailbox-manager.h new file mode 100644 index 0000000..24cd16b --- /dev/null +++ b/gxp-mailbox-manager.h @@ -0,0 +1,137 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +/* + * Mailbox manager abstracts the mailbox interfaces of user commands. + * + * Copyright (C) 2022 Google LLC + */ + +#ifndef __GXP_MAILBOX_MANAGER_H__ +#define __GXP_MAILBOX_MANAGER_H__ + +#include "gxp-internal.h" + +struct gxp_mailbox; + +typedef void __iomem *(*get_mailbox_base_t)(struct gxp_dev *gxp, uint index); + +/* + * Following callbacks will be used for manipulating the mailbox to communicating with the + * firmware. By using this callbacks instead of calling the functions of each interface directly, + * we can abstract the mailbox and reduce effort of updating the codes outside of the mailbox when + * we refactor the mailbox in the future. + */ + +/* + * Called when allocates a mailbox. The mailbox will be release by the `release_mailbox_t`. + * + * Return a pointer of allocated mailbox or an error pointer if error occurred. + * + * This callback is required if the device is in direct mode, otherwise it is optional. + */ +typedef struct gxp_mailbox *(*allocate_mailbox_t)( + struct gxp_mailbox_manager *mgr, struct gxp_virtual_device *vd, + uint virt_core, u8 core_id); + +/* + * Called to release @mailbox previously allocated by `allocate_mailbox_t`. + * + * This callback is required if the device is in direct mode, otherwise it is optional. + */ +typedef void (*release_mailbox_t)(struct gxp_mailbox_manager *mgr, + struct gxp_virtual_device *vd, uint virt_core, + struct gxp_mailbox *mailbox); + +/* Called when resets the @mailbox. */ +typedef void (*reset_mailbox_t)(struct gxp_mailbox *mailbox); + +/* + * Called when requests synchronous commands. This callback will be called from the + * `gxp_debugfs_mailbox` function. The response will be returned to the @resp_seq, @resp_status + * and `retval` of `struct gxp_response` will be returned as the return value of this function. + * You can pass NULL to @resp_seq and @resp_status if you don't need the result. See the + * `struct gxp_response` for the details. + * + * Returns the value `retval` of `struct gxp_response` when the request succeeds. Otherwise, + * returns a negative value as an error. + * + * This callback is always required regardless of the mode of device. + */ +typedef int (*execute_cmd_t)(struct gxp_client *client, + struct gxp_mailbox *mailbox, int virt_core, + u16 cmd_code, u8 cmd_priority, u64 cmd_daddr, + u32 cmd_size, u32 cmd_flags, u8 num_cores, + struct gxp_power_states power_states, + u64 *resp_seq, u16 *resp_status); + +/* + * Called when requests asynchronous commands. This callback will be called when + * `GXP_MAILBOX_COMMAND_COMPAT` or `GXP_MAILBOX_COMMAND` ioctls are fired. The sequence number of + * the command will be returned to the @cmd_seq. @eventfd will be signalled when the response + * arrives. + * + * Returns a non-zero value when error occurs while putting the command to the cmd_queue of + * mailbox. + * + * This callback is required if the device is in direct mode, otherwise it is optional. + */ +typedef int (*execute_cmd_async_t)(struct gxp_client *client, + struct gxp_mailbox *mailbox, int virt_core, + u16 cmd_code, u8 cmd_priority, u64 cmd_daddr, + u32 cmd_size, u32 cmd_flags, + struct gxp_power_states power_states, + u64 *cmd_seq); + +/* + * Called when waiting for an asynchronous response which is requested by `execute_cmd_async`. + * This callback will be called when `GXP_MAILBOX_RESPONSE` ioctl is fired. The response will be + * returned to the @resp_seq, @resp_status and @resp_retval. You can pass NULL to them if you don't + * need the result. See the `struct gxp_response` for the details. The corresponding error code of + * the response status will be set to the @error_code. + * + * Returns 0 if it succeed to get the response. Otherwise, returns a non-zero value as an error. + * + * This callback is required if the device is in direct mode, otherwise it is optional. + */ +typedef int (*wait_async_resp_t)(struct gxp_client *client, int virt_core, + u64 *resp_seq, u16 *resp_status, + u32 *resp_retval, u16 *error_code); + +/* + * Called when cleans up unconsumed async responses in the queue which arrived or timed out. + * This callback will be called when the @vd is released. + * + * This callback is always required regardless of the mode of device. + */ +typedef void (*release_unconsumed_async_resps_t)(struct gxp_virtual_device *vd); + +/* + * This structure manages how the mailbox works with user commands. + * The way how the mailbox works is dependent on the what kind of interface is used by the device. + * To minimize the effort of updating the codes outside of the mailbox, it abstracts the interfaces + * by defining the callbacks above. + */ +struct gxp_mailbox_manager { + struct gxp_dev *gxp; + u8 num_cores; + struct gxp_mailbox **mailboxes; + get_mailbox_base_t get_mailbox_csr_base; + get_mailbox_base_t get_mailbox_data_base; + allocate_mailbox_t allocate_mailbox; + release_mailbox_t release_mailbox; + reset_mailbox_t reset_mailbox; + execute_cmd_t execute_cmd; + execute_cmd_async_t execute_cmd_async; + wait_async_resp_t wait_async_resp; + release_unconsumed_async_resps_t release_unconsumed_async_resps; +}; + +/* + * Allocate the mailbox manager. + * + * In general, only one mailbox manager will be used by @gxp. What kind of mailbox interface will + * be used is decided internally. + */ +struct gxp_mailbox_manager *gxp_mailbox_create_manager(struct gxp_dev *gxp, + uint num_cores); + +#endif /* __GXP_MAILBOX_MANAGER_H__ */ |