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