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 */
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 *
91 * Return: 0 if a frame is available, else a negative error code.
92 */
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 *
105 * Return: 0 if OK, else a negative error code.
106 */
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 *
119 * Return: 0 if a frame is available, else a negative error code.
120 */
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 *
133 * Return: 0 if OK, else a negative error code.
134 */
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 *
144 * Return: 0 if the channel is ready for communication, or -EAGAIN if a
145 * 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 *
170 * Return: 0 if OK, else a negative error code.
171 */
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
177