Stephen Warren | d010783 | 2016-05-13 15:50:29 -0600 | [diff] [blame] | 1 | /* |
| 2 | * Copyright (c) 2016, NVIDIA CORPORATION. |
| 3 | * |
| 4 | * SPDX-License-Identifier: GPL-2.0 |
| 5 | */ |
| 6 | |
Stephen Warren | 3cdf676 | 2016-06-17 09:43:56 -0600 | [diff] [blame] | 7 | #ifndef _MAILBOX_H |
| 8 | #define _MAILBOX_H |
Stephen Warren | d010783 | 2016-05-13 15:50:29 -0600 | [diff] [blame] | 9 | |
| 10 | /** |
| 11 | * A mailbox is a hardware mechanism for transferring small fixed-size messages |
| 12 | * and/or notifications between the CPU on which U-Boot runs and some other |
| 13 | * device such as an auxiliary CPU running firmware or a hardware module. |
| 14 | * |
| 15 | * Data transfer is optional; a mailbox may consist solely of a notification |
| 16 | * mechanism. When data transfer is implemented, it is via HW registers or |
| 17 | * FIFOs, rather than via RAM-based buffers. The mailbox API generally |
| 18 | * implements any communication protocol enforced solely by hardware, and |
| 19 | * leaves any higher-level protocols to other layers. |
| 20 | * |
| 21 | * A mailbox channel is a bi-directional mechanism that can send a message or |
| 22 | * notification to a single specific remote entity, and receive messages or |
| 23 | * notifications from that entity. The size, content, and format of such |
| 24 | * messages is defined by the mailbox implementation, or the remote entity with |
| 25 | * which it communicates; there is no general standard at this API level. |
| 26 | * |
| 27 | * A driver that implements UCLASS_MAILBOX is a mailbox provider. A provider |
| 28 | * will often implement multiple separate mailbox channels, since the hardware |
Stephen Warren | 3cdf676 | 2016-06-17 09:43:56 -0600 | [diff] [blame] | 29 | * it manages often has this capability. mailbox-uclass.h describes the |
Stephen Warren | d010783 | 2016-05-13 15:50:29 -0600 | [diff] [blame] | 30 | * interface which mailbox providers must implement. |
| 31 | * |
| 32 | * Mailbox consumers/clients generate and send, or receive and process, |
| 33 | * messages. This header file describes the API used by clients. |
| 34 | */ |
| 35 | |
| 36 | struct udevice; |
| 37 | |
| 38 | /** |
| 39 | * struct mbox_chan - A handle to a single mailbox channel. |
| 40 | * |
| 41 | * Clients provide storage for channels. The content of the channel structure |
| 42 | * is managed solely by the mailbox API and mailbox drivers. A mailbox channel |
| 43 | * is initialized by "get"ing the mailbox. The channel struct is passed to all |
| 44 | * other mailbox APIs to identify which mailbox to operate upon. |
| 45 | * |
| 46 | * @dev: The device which implements the mailbox. |
| 47 | * @id: The mailbox channel ID within the provider. |
| 48 | * |
| 49 | * Currently, the mailbox API assumes that a single integer ID is enough to |
| 50 | * identify and configure any mailbox channel for any mailbox provider. If this |
| 51 | * assumption becomes invalid in the future, the struct could be expanded to |
| 52 | * either (a) add more fields to allow mailbox providers to store additional |
| 53 | * information, or (b) replace the id field with an opaque pointer, which the |
| 54 | * provider would dynamically allocated during its .of_xlate op, and process |
| 55 | * during is .request op. This may require the addition of an extra op to clean |
| 56 | * up the allocation. |
| 57 | */ |
| 58 | struct mbox_chan { |
| 59 | struct udevice *dev; |
| 60 | /* |
| 61 | * Written by of_xlate. We assume a single id is enough for now. In the |
| 62 | * future, we might add more fields here. |
| 63 | */ |
| 64 | unsigned long id; |
| 65 | }; |
| 66 | |
| 67 | /** |
| 68 | * mbox_get_by_index - Get/request a mailbox by integer index |
| 69 | * |
| 70 | * This looks up and requests a mailbox channel. The index is relative to the |
| 71 | * client device; each device is assumed to have n mailbox channels associated |
| 72 | * with it somehow, and this function finds and requests one of them. The |
| 73 | * mapping of client device channel indices to provider channels may be via |
| 74 | * device-tree properties, board-provided mapping tables, or some other |
| 75 | * mechanism. |
| 76 | * |
| 77 | * @dev: The client device. |
| 78 | * @index: The index of the mailbox channel to request, within the |
| 79 | * client's list of channels. |
| 80 | * @chan A pointer to a channel object to initialize. |
| 81 | * @return 0 if OK, or a negative error code. |
| 82 | */ |
| 83 | int mbox_get_by_index(struct udevice *dev, int index, struct mbox_chan *chan); |
| 84 | |
| 85 | /** |
| 86 | * mbox_get_by_name - Get/request a mailbox by name |
| 87 | * |
| 88 | * This looks up and requests a mailbox channel. The name is relative to the |
| 89 | * client device; each device is assumed to have n mailbox channels associated |
| 90 | * with it somehow, and this function finds and requests one of them. The |
| 91 | * mapping of client device channel names to provider channels may be via |
| 92 | * device-tree properties, board-provided mapping tables, or some other |
| 93 | * mechanism. |
| 94 | * |
| 95 | * @dev: The client device. |
| 96 | * @name: The name of the mailbox channel to request, within the client's |
| 97 | * list of channels. |
| 98 | * @chan A pointer to a channel object to initialize. |
| 99 | * @return 0 if OK, or a negative error code. |
| 100 | */ |
| 101 | int mbox_get_by_name(struct udevice *dev, const char *name, |
| 102 | struct mbox_chan *chan); |
| 103 | |
| 104 | /** |
| 105 | * mbox_free - Free a previously requested mailbox channel. |
| 106 | * |
| 107 | * @chan: A channel object that was previously successfully requested by |
| 108 | * calling mbox_get_by_*(). |
| 109 | * @return 0 if OK, or a negative error code. |
| 110 | */ |
| 111 | int mbox_free(struct mbox_chan *chan); |
| 112 | |
| 113 | /** |
| 114 | * mbox_send - Send a message over a mailbox channel |
| 115 | * |
| 116 | * This function will send a message to the remote entity. It may return before |
| 117 | * the remote entity has received and/or processed the message. |
| 118 | * |
| 119 | * @chan: A channel object that was previously successfully requested by |
| 120 | * calling mbox_get_by_*(). |
| 121 | * @data: A pointer to the message to transfer. The format and size of |
| 122 | * the memory region pointed at by @data is determined by the |
| 123 | * mailbox provider. Providers that solely transfer notifications |
| 124 | * will ignore this parameter. |
| 125 | * @return 0 if OK, or a negative error code. |
| 126 | */ |
| 127 | int mbox_send(struct mbox_chan *chan, const void *data); |
| 128 | |
| 129 | /** |
| 130 | * mbox_recv - Receive any available message from a mailbox channel |
| 131 | * |
| 132 | * This function will wait (up to the specified @timeout_us) for a message to |
| 133 | * be sent by the remote entity, and write the content of any such message |
| 134 | * into a caller-provided buffer. |
| 135 | * |
| 136 | * @chan: A channel object that was previously successfully requested by |
| 137 | * calling mbox_get_by_*(). |
| 138 | * @data: A pointer to the buffer to receive the message. The format and |
| 139 | * size of the memory region pointed at by @data is determined by |
| 140 | * the mailbox provider. Providers that solely transfer |
| 141 | * notifications will ignore this parameter. |
| 142 | * @timeout_us: The maximum time to wait for a message to be available, in |
| 143 | * micro-seconds. A value of 0 does not wait at all. |
| 144 | * @return 0 if OK, -ENODATA if no message was available, or a negative error |
| 145 | * code. |
| 146 | */ |
| 147 | int mbox_recv(struct mbox_chan *chan, void *data, ulong timeout_us); |
| 148 | |
| 149 | #endif |