1 /*
2  * Copyright (c) 2021-2022 Arm Limited. All rights reserved.
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *     http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 
17 /**
18  * \file atu_rss_drv.h
19  * \brief Driver for Arm Address Translation Unit (ATU).
20  */
21 
22 #ifndef __ATU_RSS_DRV_H__
23 #define __ATU_RSS_DRV_H__
24 
25 #include <stdint.h>
26 #include <stdbool.h>
27 
28 #ifdef __cplusplus
29 extern "C" {
30 #endif
31 
32 /**
33  * \brief Arm ATU error enumeration types
34  */
35 enum atu_error_t {
36     ATU_ERR_NONE,
37     ATU_ERR_INVALID_REGION,
38     ATU_ERR_INVALID_ADDRESS,
39     ATU_ERR_INVALID_ARG,
40 };
41 
42 /**
43  * \brief Allowed output bus attribute options for ATU region
44  */
45 enum atu_roba_t {
46     ATU_ROBA_PASSTHROUGH   = (0x0u),
47     ATU_ROBA_RESERVED      = (0x1u),
48     ATU_ROBA_SET_0         = (0x2u),
49     ATU_ROBA_SET_1         = (0x3u),
50 };
51 
52 /**
53  * \brief Arm ATU device configuration structure
54  */
55 struct atu_dev_cfg_t {
56     const uint32_t base;                         /*!< ATU base address */
57 };
58 
59 /**
60  * \brief Arm ATU device structure
61  */
62 struct atu_dev_t {
63     const struct atu_dev_cfg_t* const cfg;       /*!< ATU configuration */
64 };
65 
66 /**
67  * \brief Gets the ATU page size.
68  *
69  * \param[in] dev                ATU device struct \ref atu_dev_t
70  *
71  * \return Returns page size in bytes
72  *
73  * \note This function doesn't check if dev is NULL.
74  */
75 uint16_t get_page_size(struct atu_dev_t* dev);
76 
77 /**
78  * \brief Gets the number of ATU regions supported.
79  *
80  * \param[in] dev                ATU device struct \ref atu_dev_t
81  *
82  * \return Returns region count
83  *
84  * \note This function doesn't check if dev is NULL.
85  */
86 uint8_t get_supported_region_count(struct atu_dev_t* dev);
87 
88 /**
89  * \brief Enables the ATU region.
90  *
91  * \param[in] dev                ATU device struct \ref atu_dev_t
92  * \param[in] region             ATU region number to be enabled
93  *
94  * \return Returns error code as specified in \ref atu_error_t
95  *
96  * \note This function doesn't check if dev is NULL.
97  */
98 enum atu_error_t enable_atu_region(struct atu_dev_t* dev, uint8_t region);
99 
100 /**
101  * \brief Disables the ATU region.
102  *
103  * \param[in] dev                ATU device struct \ref atu_dev_t
104  * \param[in] region             ATU region number to be disabled
105  *
106  * \return Returns error code as specified in \ref atu_error_t
107  *
108  * \note This function doesn't check if dev is NULL.
109  */
110 enum atu_error_t disable_atu_region(struct atu_dev_t* dev, uint8_t region);
111 
112 /**
113  * \brief Check if Mismatch Error(ME) interrupt is waiting
114  *
115  * \param[in] dev                ATU device struct \ref atu_dev_t
116  *
117  * \return Returns bool, true if ME interrupt is waiting, false otherwise
118  *
119  * \note This function doesn't check if dev is NULL.
120  */
121 bool me_interrupt_is_waiting(struct atu_dev_t* dev);
122 
123 /**
124  * \brief Enables the ATU Mismatch Error(ME) Interrupt.
125  *
126  * \param[in] dev                ATU device struct \ref atu_dev_t
127  *
128  * \note This function doesn't check if dev is NULL.
129  */
130 void enable_me_interrupt(struct atu_dev_t* dev);
131 
132 /**
133  * \brief Clears the ATU Mismatch Error(ME) Interrupt.
134  *
135  * \param[in] dev                ATU device struct \ref atu_dev_t
136  *
137  * \note This function doesn't check if dev is NULL.
138  */
139 void clear_me_interrupt(struct atu_dev_t* dev);
140 
141 /**
142  * \brief Gets the ATU Mismatch address.
143  *
144  * \param[in] dev                ATU device struct \ref atu_dev_t
145  *
146  * \return Returns the ATU Mismatch address.
147  *
148  * \note This function doesn't check if dev is NULL.
149  */
150 uint32_t get_mismatch_address(struct atu_dev_t* dev);
151 
152 /**
153  * \brief Sets the ATU logical address start.
154  *
155  * \param[in] dev                ATU device struct \ref atu_dev_t
156  * \param[in] address            start address
157  * \param[in] region             region number
158  *
159  * \return Returns error code as specified in \ref atu_error_t
160  *
161  * \note This function doesn't check if dev is NULL.
162  */
163 enum atu_error_t set_start_logical_address(struct atu_dev_t* dev,
164                     uint32_t address, uint8_t region);
165 
166 /**
167  * \brief Sets the ATU logical address end.
168  *
169  * \param[in] dev                ATU device struct \ref atu_dev_t
170  * \param[in] address            end address
171  * \param[in] region             region number
172  *
173  * \return Returns error code as specified in \ref atu_error_t
174  *
175  * \note This function doesn't check if dev is NULL.
176  */
177 enum atu_error_t set_end_logical_address(struct atu_dev_t* dev,
178                     uint32_t address, uint8_t region);
179 
180 /**
181  * \brief Sets the ATU add value for translation.
182  *
183  * \param[in] dev                ATU device struct \ref atu_dev_t
184  * \param[in] offset_address     offset address to calculate the add value
185  * \param[in] region             region number
186  *
187  * \return Returns error code as specified in \ref atu_error_t
188  *
189  * \note This function doesn't check if dev is NULL.
190  */
191 enum atu_error_t set_add_value(struct atu_dev_t* dev,
192                     uint64_t offset_address, uint8_t region);
193 
194 /**
195  * \brief Sets the ATU AXNSC.
196  *
197  * \param[in] dev                ATU device struct \ref atu_dev_t
198  * \param[in] val                value
199  * \param[in] region             region number
200  *
201  * \return Returns error code as specified in \ref atu_error_t
202  *
203  * \note This function doesn't check if dev is NULL.
204  */
205 enum atu_error_t set_axnsc(struct atu_dev_t* dev,
206                     enum atu_roba_t val, uint8_t region);
207 
208 /**
209  * \brief Sets the ATU AXCACHE3.
210  *
211  * \param[in] dev                ATU device struct \ref atu_dev_t
212  * \param[in] val                value
213  * \param[in] region             region number
214  *
215  * \return Returns error code as specified in \ref atu_error_t
216  *
217  * \note This function doesn't check if dev is NULL.
218  */
219 enum atu_error_t set_axcache3(struct atu_dev_t* dev,
220                     enum atu_roba_t val, uint8_t region);
221 
222 /**
223  * \brief Sets the ATU AXCACHE2.
224  *
225  * \param[in] dev                ATU device struct \ref atu_dev_t
226  * \param[in] val                value
227  * \param[in] region             region number
228  *
229  * \return Returns error code as specified in \ref atu_error_t
230  *
231  * \note This function doesn't check if dev is NULL.
232  */
233 enum atu_error_t set_axcache2(struct atu_dev_t* dev,
234                     enum atu_roba_t val, uint8_t region);
235 
236 /**
237  * \brief Sets the ATU AXCACHE1.
238  *
239  * \param[in] dev                ATU device struct \ref atu_dev_t
240  * \param[in] val                value
241  * \param[in] region             region number
242  *
243  * \return Returns error code as specified in \ref atu_error_t
244  *
245  * \note This function doesn't check if dev is NULL.
246  */
247 enum atu_error_t set_axcache1(struct atu_dev_t* dev,
248                     enum atu_roba_t val, uint8_t region);
249 
250 /**
251  * \brief Sets the ATU AXCACHE0.
252  *
253  * \param[in] dev                ATU device struct \ref atu_dev_t
254  * \param[in] val                value
255  * \param[in] region             region number
256  *
257  * \return Returns error code as specified in \ref atu_error_t
258  *
259  * \note This function doesn't check if dev is NULL.
260  */
261 enum atu_error_t set_axcache0(struct atu_dev_t* dev,
262                     enum atu_roba_t val, uint8_t region);
263 
264 /**
265  * \brief Sets the ATU AXPROT2.
266  *
267  * \param[in] dev                ATU device struct \ref atu_dev_t
268  * \param[in] val                value
269  * \param[in] region             region number
270  *
271  * \return Returns error code as specified in \ref atu_error_t
272  *
273  * \note This function doesn't check if dev is NULL.
274  */
275 enum atu_error_t set_axprot2(struct atu_dev_t* dev,
276                     enum atu_roba_t val, uint8_t region);
277 
278 /**
279  * \brief Sets the ATU AXPROT1.
280  *
281  * \param[in] dev                ATU device struct \ref atu_dev_t
282  * \param[in] val                value
283  * \param[in] region             region number
284  *
285  * \return Returns error code as specified in \ref atu_error_t
286  *
287  * \note This function doesn't check if dev is NULL.
288  */
289 enum atu_error_t set_axprot1(struct atu_dev_t* dev,
290                     enum atu_roba_t val, uint8_t region);
291 
292 /**
293  * \brief Sets the ATU AXPROT0.
294  *
295  * \param[in] dev                ATU device struct \ref atu_dev_t
296  * \param[in] val                value
297  * \param[in] region             region number
298  *
299  * \return Returns error code as specified in \ref atu_error_t
300  *
301  * \note This function doesn't check if dev is NULL.
302  */
303 enum atu_error_t set_axprot0(struct atu_dev_t* dev,
304                     enum atu_roba_t val, uint8_t region);
305 
306 /**
307  * \brief Sets the ATU General Purpose Register.
308  *
309  * \param[in] dev                ATU device struct \ref atu_dev_t
310  * \param[in] val                value
311  * \param[in] region             region number
312  *
313  * \return Returns error code as specified in \ref atu_error_t
314  *
315  * \note This function doesn't check if dev is NULL.
316  */
317 enum atu_error_t set_gp_value(struct atu_dev_t* dev,
318                     uint8_t val, uint8_t region);
319 
320 /**
321  * \brief Gets the ATU General Purpose Register.
322  *
323  * \param[in] dev                ATU device struct \ref atu_dev_t
324  * \param[in] region             region number
325  *
326  * \return Returns the ATU GP value.
327  *
328  * \note This function doesn't check if dev is NULL.
329  */
330 uint8_t get_gp_value(struct atu_dev_t* dev, uint8_t region);
331 
332 /**
333  * \brief Creates and enables an ATU region.
334  *
335  * \param[in] dev                ATU device struct \ref atu_dev_t
336  * \param[in] region             ATU region number to be initialized
337  * \param[in] log_addr           Logical address
338  * \param[in] phys_addr          Physical address
339  * \param[in] size               Region size
340  *
341  * \return Returns error code as specified in \ref atu_error_t
342  */
343 enum atu_error_t atu_initialize_region(struct atu_dev_t *dev, uint8_t region,
344                                        uint32_t log_addr, uint64_t phys_addr,
345                                        uint32_t size);
346 
347 /**
348  * \brief Uninitializes an ATU region.
349  *
350  * \param[in] dev                ATU device struct \ref atu_dev_t
351  * \param[in] region             ATU region number to be uninitialized
352  *
353  * \return Returns error code as specified in \ref atu_error_t
354  */
355 enum atu_error_t atu_uninitialize_region(struct atu_dev_t *dev, uint8_t region);
356 
357 #ifdef __cplusplus
358 }
359 #endif
360 
361 #endif /* __ATU_RSS_DRV_H__ */
362