1 /*
2 * Copyright (c) 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 #ifndef __DMA350_DRV_H
18 #define __DMA350_DRV_H
19
20 #include "dma350_regdef.h"
21
22 /* For __STATIC_INLINE */
23 #include "cmsis_compiler.h"
24
25 #include <stddef.h>
26 #include <stdint.h>
27
28 #ifdef __cplusplus
29 extern "C" {
30 #endif
31
32 #define DMA_INFO_IIDR(_IMPLEMENTER_, _REVISION_, _VARIANT_, _PRODUCT_ID_) \
33 (((_IMPLEMENTER_)&0xFFFUL) | (((_REVISION_)&0xFUL) << 12) | \
34 (((_VARIANT_)&0xFUL) << 16) | (((_PRODUCT_ID_)&0xFFFUL) << 20))
35
36 #define DMA_INFO_IIDR_IMPL_ARM 0x43B
37 #define DMA_INFO_IIDR_REVISION 0x0
38 #define DMA_INFO_IIDR_VARIANT 0x0
39 #define DMA_INFO_IIDR_PROD_ID 0x3A0
40
41 #define DMA_INFO_IIDR_SUPPORTED \
42 DMA_INFO_IIDR(DMA_INFO_IIDR_IMPL_ARM, DMA_INFO_IIDR_REVISION, \
43 DMA_INFO_IIDR_VARIANT, DMA_INFO_IIDR_PROD_ID)
44
45 #define DMA_INFO_AIDR(_ARCH_MAJOR_, _ARCH_MINOR_) \
46 (((_ARCH_MAJOR_)&0xFUL) | (((_ARCH_MINOR_)&0xFUL) << 4))
47
48 #define DMA_INFO_AIDR_SUPPORTED DMA_INFO_AIDR(0, 0)
49
50 #define DMA350_MAX_NUM_CH 16
51
52 /* DMA350 state definitions */
53 #define DMA350_INITIALIZED (1UL << 0)
54
55 /* DMA350 DMA Device error enumeration types */
56 enum dma350_error_t {
57 DMA350_ERR_NONE = 0, /*!< No error */
58 DMA350_ERR_IIDR_MISMATCH, /*!< Error: DMA350 driver does not support this
59 * implementer of the hardware */
60 DMA350_ERR_AIDR_MISMATCH, /*!< Error: DMA350 driver does not support this
61 * architecture revision */
62 DMA350_ERR_NOT_INIT, /*!< Error: DMA350 not initialized */
63 DMA350_ERR_CANNOT_SET_NOW, /*!< Error: config cannot be set currently */
64 DMA350_ERR_INVALID_PARAM, /*!< Error: requested parameter is not valid */
65 };
66
67 /* ARM DMA350 DMA INFO register BUILDCFG0 field Type */
68 union dma350_dmainfo_buildcfg0_t {
69 struct {
70 uint32_t FRAMETYPE:3; /*!< bit: 0.. 2 FRAMETYPE[ 2:0] */
71 uint32_t RESERVED0:1; /*!< bit: 3 RESERVED0 */
72 uint32_t NUM_CHANNELS:6; /*!< bit: 4.. 9 NUM_CHANNELS[ 5:0] */
73 uint32_t ADDR_WIDTH:6; /*!< bit: 10..15 ADDR_WIDTH[ 5:0] */
74 uint32_t DATA_WIDTH:3; /*!< bit: 16..18 DATA_WIDTH[ 2:0] */
75 uint32_t RESERVED1:1; /*!< bit: 19 RESERVED1 */
76 uint32_t CHID_WIDTH:5; /*!< bit: 20..24 CHID_WIDTH[ 4:0] */
77 uint32_t RESERVED2:7; /*!< bit: 25..31 RESERVED2[ 6:0] */
78 } b; /*!< Structure used for bit access */
79 uint32_t w; /*!< Type used for word access */
80 };
81
82 /* ARM DMA350 DMA INFO register BUILDCFG1 field Type */
83 union dma350_dmainfo_buildcfg1_t {
84 struct {
85 uint32_t NUM_TRIGGER_IN:9; /*!< bit: 0.. 8 NUM_TRIGGER_IN[ 8:0] */
86 uint32_t NUM_TRIGGER_OUT:7; /*!< bit: 9..15 NUM_TRIGGER_OUT[ 6:0] */
87 uint32_t HAS_TRIGSEL:1; /*!< bit: 16 HAS_TRIGSEL */
88 uint32_t RESERVED0:7; /*!< bit: 17..23 RESERVED0[ 6:0] */
89 uint32_t RESERVED1:1; /*!< bit: 24 RESERVED1 */
90 uint32_t RESERVED2:7; /*!< bit: 25..31 RESERVED2[ 6:0] */
91 } b; /*!< Structure used for bit access */
92 uint32_t w; /*!< Type used for word access */
93 };
94
95 /* ARM DMA350 DMA device configuration structure */
96 struct dma350_dev_cfg_t {
97 DMASECCFG_TypeDef *dma_sec_cfg; /*!< DMA350 secure config */
98 DMASECCTRL_TypeDef *dma_sec_ctrl; /*!< DMA350 secure control */
99 DMANSECCTRL_TypeDef *dma_nsec_ctrl; /*!< DMA350 non-secure control */
100 DMAINFO_TypeDef *dma_info; /*!< DMA350 info */
101 };
102
103 /* ARM DMA350 DMA device data structure */
104 struct dma350_dev_data_t {
105 uint32_t state; /*!< Indicates if the DMA350 driver
106 * is initialized and enabled */
107 };
108
109 /* ARM DMA350 DMA device structure */
110 struct dma350_dev_t {
111 const struct dma350_dev_cfg_t *const cfg; /*!< DMA350 DMA configuration */
112 struct dma350_dev_data_t *const data; /*!< DMA350 DMA data */
113 };
114
115 /**
116 * \brief Initializes DMA350 DMA
117 *
118 * \param[in] dev DMA350 device struct \ref dma350_dev_t
119 *
120 * \return Returns error code as specified in \ref dma350_error_t
121 *
122 * \note This function doesn't check if dev is NULL.
123 */
124 enum dma350_error_t dma350_init(struct dma350_dev_t *dev);
125
126 /**
127 * \brief Checks if DMA350 device is initialised
128 *
129 * \param[in] dev DMA350 device struct \ref dma350_dev_t
130 *
131 * \return Returns true if device is initialized
132 *
133 * \note This function doesn't check if dev is NULL.
134 */
135 __STATIC_INLINE
136 uint8_t dma350_is_init(const struct dma350_dev_t *dev);
137
138 /**
139 * \brief Gets number of channels available in DMA350 device
140 *
141 * \param[in] dev DMA350 device struct \ref dma350_dev_t
142 *
143 * \return Returns number of channels
144 *
145 * \note This function doesn't check if dev is NULL or if it has been init.
146 */
147 __STATIC_INLINE
148 uint8_t dma350_get_num_ch(const struct dma350_dev_t *dev);
149
150 /**
151 * \brief Enables Security Access Violation Interrupt
152 *
153 * \param[in] dev DMA350 device struct \ref dma350_dev_t
154 *
155 * \return void
156 *
157 * \note This function doesn't check if dev is NULL.
158 */
159 void dma350_enable_secaccvio_irq(struct dma350_dev_t *dev);
160
161 /**
162 * \brief Disables Security Access Violation Interrupt
163 *
164 * \param[in] dev DMA350 device struct \ref dma350_dev_t
165 *
166 * \return void
167 *
168 * \note This function doesn't check if dev is NULL.
169 */
170 void dma350_disable_secaccvio_irq(struct dma350_dev_t *dev);
171
172 /**
173 * \brief Set Security Access Violation response to bus error
174 *
175 * \param[in] dev DMA350 device struct \ref dma350_dev_t
176 *
177 * \return void
178 *
179 * \note This function doesn't check if dev is NULL.
180 */
181 void dma350_set_secaccvio_rsp_buserr(struct dma350_dev_t *dev);
182
183 /**
184 * \brief Set Security Access Violation response to RAZ/WI
185 *
186 * \param[in] dev DMA350 device struct \ref dma350_dev_t
187 *
188 * \return void
189 *
190 * \note This function doesn't check if dev is NULL.
191 */
192 void dma350_set_secaccvio_rsp_razwi(struct dma350_dev_t *dev);
193
194 /**
195 * \brief Set Security Access Violation response to RAZ/WI
196 * Once locked, SCFGCHSEC, SCFGTRIGSEC and SCFGCTRL cannot be modified.
197 * Can only be unlocked by reset.
198 *
199 * \param[in] dev DMA350 device struct \ref dma350_dev_t
200 *
201 * \return void
202 *
203 * \note This function doesn't check if dev is NULL.
204 */
205 void dma350_lock_security_cfg(struct dma350_dev_t *dev);
206
207 /**
208 * \brief Gets Security Access Violation Interrupt status
209 *
210 * \param[in] dev DMA350 device struct \ref dma350_dev_t
211 *
212 * \return Returns true if secaccvio irq is enabled and active,
213 * false otherwise.
214 *
215 * \note This function doesn't check if dev is NULL.
216 * Cleared when secaccvio status is cleared.
217 */
218 uint8_t dma350_get_secaccvio_irq(struct dma350_dev_t *dev);
219
220 /**
221 * \brief Gets Security Access Violation status
222 *
223 * \param[in] dev DMA350 device struct \ref dma350_dev_t
224 *
225 * \return Returns true if secaccvio status active, false otherwise.
226 *
227 * \note This function doesn't check if dev is NULL.
228 */
229 uint8_t dma350_get_secaccvio_status(struct dma350_dev_t *dev);
230
231 /**
232 * \brief Clears Security Access Violation Status
233 *
234 * \param[in] dev DMA350 device struct \ref dma350_dev_t
235 *
236 * \return void
237 *
238 * \note This function doesn't check if dev is NULL.
239 */
240 void dma350_clear_secaccvio_status(struct dma350_dev_t *dev);
241
242 /**
243 * \brief Set DMA350 DMA Channel to secure.
244 *
245 * \param[in] dev DMA350 device struct \ref dma350_dev_t
246 * \param[in] channel Id of the channel to be updated
247 *
248 * \return Returns error code as specified in \ref dma350_error_t
249 *
250 * \note This function doesn't check if dev is NULL.
251 * Operation will fail if channel is enabled.
252 */
253 enum dma350_error_t dma350_set_ch_secure(struct dma350_dev_t *dev,
254 uint8_t channel);
255
256 /**
257 * \brief Set DMA350 DMA Channel to non-secure.
258 *
259 * \param[in] dev DMA350 device struct \ref dma350_dev_t
260 * \param[in] channel Id of the channel to be updated
261 *
262 * \return Returns error code as specified in \ref dma350_error_t
263 *
264 * \note This function doesn't check if dev is NULL.
265 * Operation will fail if channel is enabled.
266 */
267 enum dma350_error_t dma350_set_ch_nonsecure(struct dma350_dev_t *dev,
268 uint8_t channel);
269
270 /**
271 * \brief Set DMA350 DMA Channel to privileged.
272 *
273 * \param[in] dev DMA350 device struct \ref dma350_dev_t
274 * \param[in] channel Id of the channel to be updated
275 *
276 * \return Returns error code as specified in \ref dma350_error_t
277 *
278 * \note This function doesn't check if dev is NULL.
279 * Operation will fail if channel is enabled.
280 *
281 * \note This function sets the channel privilege according to the current
282 * channel security. When changing channel security, this setting is
283 * not transferred to the other domain. So, it is recommended that after
284 * the security of a channel is changed, the privilege level should
285 * also be set.
286 *
287 */
288 enum dma350_error_t dma350_set_ch_privileged(struct dma350_dev_t *dev,
289 uint8_t channel);
290
291 /**
292 * \brief Set DMA350 DMA Channel to unprivileged.
293 *
294 * \param[in] dev DMA350 device struct \ref dma350_dev_t
295 * \param[in] channel Id of the channel to be updated
296 *
297 * \return Returns error code as specified in \ref dma350_error_t
298 *
299 * \note This function doesn't check if dev is NULL.
300 * Operation will fail if channel is enabled.
301 */
302 enum dma350_error_t dma350_set_ch_unprivileged(struct dma350_dev_t *dev,
303 uint8_t channel);
304
305 /**
306 * \brief Set DMA350 DMA Trigger input to secure.
307 *
308 * \param[in] dev DMA350 device struct \ref dma350_dev_t
309 * \param[in] trigger Trigger input number to be updated
310 *
311 * \return Returns error code as specified in \ref dma350_error_t
312 *
313 * \note This function doesn't check if dev is NULL.
314 * Operation will fail if channel is enabled.
315 */
316 enum dma350_error_t dma350_set_trigin_secure(struct dma350_dev_t *dev,
317 uint8_t trigger);
318
319 /**
320 * \brief Set DMA350 DMA Trigger input to non-secure.
321 *
322 * \param[in] dev DMA350 device struct \ref dma350_dev_t
323 * \param[in] trigger Trigger input number to be updated
324 *
325 * \return Returns error code as specified in \ref dma350_error_t
326 *
327 * \note This function doesn't check if dev is NULL.
328 * Operation will fail if channel is enabled.
329 */
330 enum dma350_error_t dma350_set_trigin_nonsecure(struct dma350_dev_t *dev,
331 uint8_t trigger);
332
333 /**
334 * \brief Set DMA350 DMA Trigger output to secure.
335 *
336 * \param[in] dev DMA350 device struct \ref dma350_dev_t
337 * \param[in] trigger Trigger output number to be updated
338 *
339 * \return Returns error code as specified in \ref dma350_error_t
340 *
341 * \note This function doesn't check if dev is NULL.
342 * Operation will fail if channel is enabled.
343 */
344 enum dma350_error_t dma350_set_trigout_secure(struct dma350_dev_t *dev,
345 uint8_t trigger);
346
347 /**
348 * \brief Set DMA350 DMA Trigger output to non-secure.
349 *
350 * \param[in] dev DMA350 device struct \ref dma350_dev_t
351 * \param[in] trigger Trigger output number to be updated
352 *
353 * \return Returns error code as specified in \ref dma350_error_t
354 *
355 * \note This function doesn't check if dev is NULL.
356 * Operation will fail if channel is enabled.
357 */
358 enum dma350_error_t dma350_set_trigout_nonsecure(struct dma350_dev_t *dev,
359 uint8_t trigger);
360
361 __STATIC_INLINE
dma350_get_num_ch(const struct dma350_dev_t * dev)362 uint8_t dma350_get_num_ch(const struct dma350_dev_t *dev)
363 {
364 return (union dma350_dmainfo_buildcfg0_t) {
365 .w = dev->cfg->dma_info->DMA_BUILDCFG0
366 }.b.NUM_CHANNELS;
367 }
368
369 __STATIC_INLINE
dma350_is_init(const struct dma350_dev_t * dev)370 uint8_t dma350_is_init(const struct dma350_dev_t *dev)
371 {
372 return dev->data->state == DMA350_INITIALIZED;
373 }
374
375 #ifdef __cplusplus
376 }
377 #endif
378 #endif /* __DMA350_DRV_H */
379