/* 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__ */