blob: fef8b16845217f0de8dd6b6b2c803db942dfcba6 [file] [log] [blame]
Tom Rini10e47792018-05-06 17:58:06 -04001/* SPDX-License-Identifier: GPL-2.0 */
Stephen Warrenadf3abd2016-07-18 12:17:11 -06002/*
3 * Copyright (c) 2016, NVIDIA CORPORATION.
Stephen Warrenadf3abd2016-07-18 12:17:11 -06004 */
5
6#ifndef _ASM_ARCH_TEGRA_IVC_H
7#define _ASM_ARCH_TEGRA_IVC_H
8
Stephen Warrenadf3abd2016-07-18 12:17:11 -06009/*
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 */
35struct 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 */
44struct 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 *
Heinrich Schuchardt47b4c022022-01-19 18:05:50 +010091 * Return: 0 if a frame is available, else a negative error code.
Stephen Warrenadf3abd2016-07-18 12:17:11 -060092 */
93int 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 *
Heinrich Schuchardt47b4c022022-01-19 18:05:50 +0100105 * Return: 0 if OK, else a negative error code.
Stephen Warrenadf3abd2016-07-18 12:17:11 -0600106 */
107int 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 *
Heinrich Schuchardt47b4c022022-01-19 18:05:50 +0100119 * Return: 0 if a frame is available, else a negative error code.
Stephen Warrenadf3abd2016-07-18 12:17:11 -0600120 */
121int 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 *
Heinrich Schuchardt47b4c022022-01-19 18:05:50 +0100133 * Return: 0 if OK, else a negative error code.
Stephen Warrenadf3abd2016-07-18 12:17:11 -0600134 */
135int 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 *
Heinrich Schuchardt47b4c022022-01-19 18:05:50 +0100144 * Return: 0 if the channel is ready for communication, or -EAGAIN if a
Stephen Warrenadf3abd2016-07-18 12:17:11 -0600145 * channel reset is in progress.
146 */
147int 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 */
159void 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 *
Heinrich Schuchardt47b4c022022-01-19 18:05:50 +0100170 * Return: 0 if OK, else a negative error code.
Stephen Warrenadf3abd2016-07-18 12:17:11 -0600171 */
172int 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