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