1 /* SPDX-License-Identifier: GPL-2.0 */ 2 /* 3 * Copyright (c) 2016, NVIDIA CORPORATION. 4 */ 5 6 #ifndef _ASM_ARCH_TEGRA_IVC_H 7 #define _ASM_ARCH_TEGRA_IVC_H 8 9 /* 10 * Tegra IVC is a communication protocol that transfers fixed-size frames 11 * bi-directionally and in-order between the local CPU and some remote entity. 12 * Communication is via a statically sized and allocated buffer in shared 13 * memory and a notification mechanism. 14 * 15 * This API handles all aspects of the shared memory buffer's metadata, and 16 * leaves all aspects of the frame content to the calling code; frames 17 * typically contain some higher-level protocol. The notification mechanism is 18 * also handled externally to this API, since it can vary from instance to 19 * instance. 20 * 21 * The client model is to first find some free (for TX) or filled (for RX) 22 * frame, process that frame's memory buffer (fill or read it), and then 23 * inform the protocol that the frame has been filled/read, i.e. advance the 24 * write/read pointer. If the channel is full, there may be no available frames 25 * to fill/read. In this case, client code may either poll for an available 26 * frame, or wait for the remote entity to send a notification to the local 27 * CPU. 28 */ 29 30 /** 31 * struct tegra_ivc - In-memory shared memory layout. 32 * 33 * This is described in detail in ivc.c. 34 */ 35 struct tegra_ivc_channel_header; 36 37 /** 38 * struct tegra_ivc - Software state of an IVC channel. 39 * 40 * This state is internal to the IVC code and should not be accessed directly 41 * by clients. It is public solely so clients can allocate storage for the 42 * structure. 43 */ 44 struct tegra_ivc { 45 /** 46 * rx_channel - Pointer to the shared memory region used to receive 47 * messages from the remote entity. 48 */ 49 struct tegra_ivc_channel_header *rx_channel; 50 /** 51 * tx_channel - Pointer to the shared memory region used to send 52 * messages to the remote entity. 53 */ 54 struct tegra_ivc_channel_header *tx_channel; 55 /** 56 * r_pos - The position in list of frames in rx_channel that we are 57 * reading from. 58 */ 59 uint32_t r_pos; 60 /** 61 * w_pos - The position in list of frames in tx_channel that we are 62 * writing to. 63 */ 64 uint32_t w_pos; 65 /** 66 * nframes - The number of frames allocated (in each direction) in 67 * shared memory. 68 */ 69 uint32_t nframes; 70 /** 71 * frame_size - The size of each frame in shared memory. 72 */ 73 uint32_t frame_size; 74 /** 75 * notify - Function to call to notify the remote processor of a 76 * change in channel state. 77 */ 78 void (*notify)(struct tegra_ivc *); 79 }; 80 81 /** 82 * tegra_ivc_read_get_next_frame - Locate the next frame to receive. 83 * 84 * Locate the next frame to be received/processed, return the address of the 85 * frame, and do not remove it from the queue. Repeated calls to this function 86 * will return the same address until tegra_ivc_read_advance() is called. 87 * 88 * @ivc The IVC channel. 89 * @frame Pointer to be filled with the address of the frame to receive. 90 * 91 * @return 0 if a frame is available, else a negative error code. 92 */ 93 int tegra_ivc_read_get_next_frame(struct tegra_ivc *ivc, void **frame); 94 95 /** 96 * tegra_ivc_read_advance - Advance the read queue. 97 * 98 * Inform the protocol and remote entity that the frame returned by 99 * tegra_ivc_read_get_next_frame() has been processed. The remote end may then 100 * re-use it to transmit further data. Subsequent to this function returning, 101 * tegra_ivc_read_get_next_frame() will return a different frame. 102 * 103 * @ivc The IVC channel. 104 * 105 * @return 0 if OK, else a negative error code. 106 */ 107 int tegra_ivc_read_advance(struct tegra_ivc *ivc); 108 109 /** 110 * tegra_ivc_write_get_next_frame - Locate the next frame to fill for transmit. 111 * 112 * Locate the next frame to be filled for transmit, return the address of the 113 * frame, and do not add it to the queue. Repeated calls to this function 114 * will return the same address until tegra_ivc_read_advance() is called. 115 * 116 * @ivc The IVC channel. 117 * @frame Pointer to be filled with the address of the frame to fill. 118 * 119 * @return 0 if a frame is available, else a negative error code. 120 */ 121 int tegra_ivc_write_get_next_frame(struct tegra_ivc *ivc, void **frame); 122 123 /** 124 * tegra_ivc_write_advance - Advance the write queue. 125 * 126 * Inform the protocol and remote entity that the frame returned by 127 * tegra_ivc_write_get_next_frame() has been filled and should be transmitted. 128 * The remote end may then read data from it. Subsequent to this function 129 * returning, tegra_ivc_write_get_next_frame() will return a different frame. 130 * 131 * @ivc The IVC channel. 132 * 133 * @return 0 if OK, else a negative error code. 134 */ 135 int tegra_ivc_write_advance(struct tegra_ivc *ivc); 136 137 /** 138 * tegra_ivc_channel_notified - handle internal messages 139 * 140 * This function must be called following every notification. 141 * 142 * @ivc The IVC channel. 143 * 144 * @return 0 if the channel is ready for communication, or -EAGAIN if a 145 * channel reset is in progress. 146 */ 147 int tegra_ivc_channel_notified(struct tegra_ivc *ivc); 148 149 /** 150 * tegra_ivc_channel_reset - initiates a reset of the shared memory state 151 * 152 * This function must be called after a channel is initialized but before it 153 * is used for communication. The channel will be ready for use when a 154 * subsequent call to notify the remote of the channel reset indicates the 155 * reset operation is complete. 156 * 157 * @ivc The IVC channel. 158 */ 159 void tegra_ivc_channel_reset(struct tegra_ivc *ivc); 160 161 /** 162 * tegra_ivc_init - Initialize a channel's software state. 163 * 164 * @ivc The IVC channel. 165 * @rx_base Address of the the RX shared memory buffer. 166 * @tx_base Address of the the TX shared memory buffer. 167 * @nframes Number of frames in each shared memory buffer. 168 * @frame_size Size of each frame. 169 * 170 * @return 0 if OK, else a negative error code. 171 */ 172 int tegra_ivc_init(struct tegra_ivc *ivc, ulong rx_base, ulong tx_base, 173 uint32_t nframes, uint32_t frame_size, 174 void (*notify)(struct tegra_ivc *)); 175 176 #endif 177