Merge tag 'u-boot-atmel-fixes-2020.07-a' of https://gitlab.denx.de/u-boot/custodians...
[oweals/u-boot.git] / arch / arm / include / asm / arch-tegra / ivc.h
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