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 #include "dma350_drv.h"
18
19 #include <stddef.h>
20 #include <stdint.h>
21
22
dma350_init(struct dma350_dev_t * dev)23 enum dma350_error_t dma350_init(struct dma350_dev_t *dev)
24 {
25 if (dev->cfg->dma_info->IIDR != DMA_INFO_IIDR_SUPPORTED) {
26 return DMA350_ERR_IIDR_MISMATCH;
27 }
28 if (dev->cfg->dma_info->AIDR != DMA_INFO_AIDR_SUPPORTED) {
29 return DMA350_ERR_AIDR_MISMATCH;
30 }
31 dev->data->state = DMA350_INITIALIZED;
32 return DMA350_ERR_NONE;
33 }
34
dma350_enable_secaccvio_irq(struct dma350_dev_t * dev)35 void dma350_enable_secaccvio_irq(struct dma350_dev_t *dev)
36 {
37 dev->cfg->dma_sec_cfg->SCFG_CTRL =
38 (dev->cfg->dma_sec_cfg->SCFG_CTRL |
39 DMA_SCFG_CTRL_INTREN_SECACCVIO_Msk) &
40 ~(DMA_SCFG_INTRSTATUS_STAT_SECACCVIO_Msk);
41 }
42
dma350_disable_secaccvio_irq(struct dma350_dev_t * dev)43 void dma350_disable_secaccvio_irq(struct dma350_dev_t *dev)
44 {
45 dev->cfg->dma_sec_cfg->SCFG_CTRL =
46 (dev->cfg->dma_sec_cfg->SCFG_CTRL &
47 ~(DMA_SCFG_CTRL_INTREN_SECACCVIO_Msk)) &
48 ~(DMA_SCFG_INTRSTATUS_STAT_SECACCVIO_Msk);
49 }
50
dma350_set_secaccvio_rsp_buserr(struct dma350_dev_t * dev)51 void dma350_set_secaccvio_rsp_buserr(struct dma350_dev_t *dev)
52 {
53 dev->cfg->dma_sec_cfg->SCFG_CTRL =
54 (dev->cfg->dma_sec_cfg->SCFG_CTRL |
55 DMA_SCFG_CTRL_RSPTYPE_SECACCVIO_Msk) &
56 ~(DMA_SCFG_INTRSTATUS_STAT_SECACCVIO_Msk);
57 }
58
dma350_set_secaccvio_rsp_razwi(struct dma350_dev_t * dev)59 void dma350_set_secaccvio_rsp_razwi(struct dma350_dev_t *dev)
60 {
61 dev->cfg->dma_sec_cfg->SCFG_CTRL =
62 (dev->cfg->dma_sec_cfg->SCFG_CTRL &
63 ~(DMA_SCFG_CTRL_RSPTYPE_SECACCVIO_Msk)) &
64 ~(DMA_SCFG_INTRSTATUS_STAT_SECACCVIO_Msk);
65 }
66
dma350_lock_security_cfg(struct dma350_dev_t * dev)67 void dma350_lock_security_cfg(struct dma350_dev_t *dev)
68 {
69 dev->cfg->dma_sec_cfg->SCFG_CTRL =
70 (dev->cfg->dma_sec_cfg->SCFG_CTRL | DMA_SCFG_CTRL_SEC_CFG_LCK_Msk) &
71 ~(DMA_SCFG_INTRSTATUS_STAT_SECACCVIO_Msk);
72 }
73
dma350_get_secaccvio_irq(struct dma350_dev_t * dev)74 uint8_t dma350_get_secaccvio_irq(struct dma350_dev_t *dev)
75 {
76 return dev->cfg->dma_sec_cfg->SCFG_CTRL &
77 DMA_SCFG_INTRSTATUS_INTR_SECACCVIO_Msk;
78 }
79
dma350_get_secaccvio_status(struct dma350_dev_t * dev)80 uint8_t dma350_get_secaccvio_status(struct dma350_dev_t *dev)
81 {
82 return (uint8_t)(dev->cfg->dma_sec_cfg->SCFG_CTRL &
83 DMA_SCFG_INTRSTATUS_STAT_SECACCVIO_Msk);
84 }
85
dma350_clear_secaccvio_status(struct dma350_dev_t * dev)86 void dma350_clear_secaccvio_status(struct dma350_dev_t *dev)
87 {
88 dev->cfg->dma_sec_cfg->SCFG_CTRL = dev->cfg->dma_sec_cfg->SCFG_CTRL |
89 DMA_SCFG_INTRSTATUS_STAT_SECACCVIO_Msk;
90 }
91
dma350_set_ch_secure(struct dma350_dev_t * dev,uint8_t channel)92 enum dma350_error_t dma350_set_ch_secure(struct dma350_dev_t *dev,
93 uint8_t channel)
94 {
95 if (!dma350_is_init(dev)) {
96 return DMA350_ERR_NOT_INIT;
97 }
98
99 dev->cfg->dma_sec_cfg->SCFG_CHSEC0 =
100 dev->cfg->dma_sec_cfg->SCFG_CHSEC0 & ~(0x1UL << channel);
101 if (dev->cfg->dma_sec_cfg->SCFG_CHSEC0 & (0x1UL << channel)) {
102 return DMA350_ERR_CANNOT_SET_NOW;
103 } else {
104 return DMA350_ERR_NONE;
105 }
106 }
107
dma350_set_ch_nonsecure(struct dma350_dev_t * dev,uint8_t channel)108 enum dma350_error_t dma350_set_ch_nonsecure(struct dma350_dev_t *dev,
109 uint8_t channel)
110 {
111 if (!dma350_is_init(dev)) {
112 return DMA350_ERR_NOT_INIT;
113 }
114
115 dev->cfg->dma_sec_cfg->SCFG_CHSEC0 =
116 dev->cfg->dma_sec_cfg->SCFG_CHSEC0 | (0x1UL << channel);
117 if (dev->cfg->dma_sec_cfg->SCFG_CHSEC0 & (0x1UL << channel)) {
118 return DMA350_ERR_NONE;
119 } else {
120 return DMA350_ERR_CANNOT_SET_NOW;
121 }
122 }
123
dma350_set_ch_privileged(struct dma350_dev_t * dev,uint8_t channel)124 enum dma350_error_t dma350_set_ch_privileged(struct dma350_dev_t *dev,
125 uint8_t channel)
126 {
127 if (!dma350_is_init(dev)) {
128 return DMA350_ERR_NOT_INIT;
129 }
130 if (dev->cfg->dma_sec_cfg->SCFG_CHSEC0 & (0x1UL << channel)) {
131 /* Channel is Non-secure */
132 dev->cfg->dma_nsec_ctrl->NSEC_CHPTR = channel;
133 dev->cfg->dma_nsec_ctrl->NSEC_CHCFG =
134 dev->cfg->dma_nsec_ctrl->NSEC_CHCFG | DMA_NSEC_CHCFG_CHPRIV_Msk;
135 if (dev->cfg->dma_nsec_ctrl->NSEC_CHCFG & (DMA_NSEC_CHCFG_CHPRIV_Msk)) {
136 return DMA350_ERR_NONE;
137 } else {
138 return DMA350_ERR_CANNOT_SET_NOW;
139 }
140 } else {
141 /* Channel is Secure */
142 dev->cfg->dma_sec_ctrl->SEC_CHPTR = channel;
143 dev->cfg->dma_sec_ctrl->SEC_CHCFG =
144 dev->cfg->dma_sec_ctrl->SEC_CHCFG | DMA_SEC_CHCFG_CHPRIV_Msk;
145 if (dev->cfg->dma_sec_ctrl->SEC_CHCFG & (DMA_SEC_CHCFG_CHPRIV_Msk)) {
146 return DMA350_ERR_NONE;
147 } else {
148 return DMA350_ERR_CANNOT_SET_NOW;
149 }
150 }
151 }
152
dma350_set_ch_unprivileged(struct dma350_dev_t * dev,uint8_t channel)153 enum dma350_error_t dma350_set_ch_unprivileged(struct dma350_dev_t *dev,
154 uint8_t channel)
155 {
156 if (!dma350_is_init(dev)) {
157 return DMA350_ERR_NOT_INIT;
158 }
159 if (dev->cfg->dma_sec_cfg->SCFG_CHSEC0 & (0x1UL << channel)) {
160 /* Channel is Non-secure */
161 dev->cfg->dma_nsec_ctrl->NSEC_CHPTR = channel;
162 dev->cfg->dma_nsec_ctrl->NSEC_CHCFG =
163 dev->cfg->dma_nsec_ctrl->NSEC_CHCFG & ~(DMA_NSEC_CHCFG_CHPRIV_Msk);
164 if (dev->cfg->dma_nsec_ctrl->NSEC_CHCFG & (DMA_NSEC_CHCFG_CHPRIV_Msk)) {
165 return DMA350_ERR_CANNOT_SET_NOW;
166 } else {
167 return DMA350_ERR_NONE;
168 }
169 } else {
170 /* Channel is Secure */
171 dev->cfg->dma_sec_ctrl->SEC_CHPTR = channel;
172 dev->cfg->dma_sec_ctrl->SEC_CHCFG =
173 dev->cfg->dma_sec_ctrl->SEC_CHCFG & ~(DMA_SEC_CHCFG_CHPRIV_Msk);
174 if (dev->cfg->dma_sec_ctrl->SEC_CHCFG & (DMA_SEC_CHCFG_CHPRIV_Msk)) {
175 return DMA350_ERR_CANNOT_SET_NOW;
176 } else {
177 return DMA350_ERR_NONE;
178 }
179 }
180 }
181
dma350_set_trigin_secure(struct dma350_dev_t * dev,uint8_t trigger)182 enum dma350_error_t dma350_set_trigin_secure(struct dma350_dev_t *dev,
183 uint8_t trigger)
184 {
185 if (!dma350_is_init(dev)) {
186 return DMA350_ERR_NOT_INIT;
187 }
188
189 if(trigger >= 32) {
190 return DMA350_ERR_INVALID_PARAM;
191 }
192
193 dev->cfg->dma_sec_cfg->SCFG_TRIGINSEC0 =
194 dev->cfg->dma_sec_cfg->SCFG_TRIGINSEC0 & ~(0x1UL << trigger);
195 if (dev->cfg->dma_sec_cfg->SCFG_TRIGINSEC0 & (0x1UL << trigger)) {
196 return DMA350_ERR_CANNOT_SET_NOW;
197 } else {
198 return DMA350_ERR_NONE;
199 }
200 }
201
dma350_set_trigin_nonsecure(struct dma350_dev_t * dev,uint8_t trigger)202 enum dma350_error_t dma350_set_trigin_nonsecure(struct dma350_dev_t *dev,
203 uint8_t trigger)
204 {
205 if (!dma350_is_init(dev)) {
206 return DMA350_ERR_NOT_INIT;
207 }
208
209 if(trigger >= 32) {
210 return DMA350_ERR_INVALID_PARAM;
211 }
212
213 dev->cfg->dma_sec_cfg->SCFG_TRIGINSEC0 =
214 dev->cfg->dma_sec_cfg->SCFG_TRIGINSEC0 | (0x1UL << trigger);
215 if (dev->cfg->dma_sec_cfg->SCFG_TRIGINSEC0 & (0x1UL << trigger)) {
216 return DMA350_ERR_NONE;
217 } else {
218 return DMA350_ERR_CANNOT_SET_NOW;
219 }
220 }
221
dma350_set_trigout_secure(struct dma350_dev_t * dev,uint8_t trigger)222 enum dma350_error_t dma350_set_trigout_secure(struct dma350_dev_t *dev,
223 uint8_t trigger)
224 {
225 if (!dma350_is_init(dev)) {
226 return DMA350_ERR_NOT_INIT;
227 }
228
229 if(trigger >= 32) {
230 return DMA350_ERR_INVALID_PARAM;
231 }
232
233 dev->cfg->dma_sec_cfg->SCFG_TRIGOUTSEC0 =
234 dev->cfg->dma_sec_cfg->SCFG_TRIGOUTSEC0 & ~(0x1UL << trigger);
235 if (dev->cfg->dma_sec_cfg->SCFG_TRIGOUTSEC0 & (0x1UL << trigger)) {
236 return DMA350_ERR_CANNOT_SET_NOW;
237 } else {
238 return DMA350_ERR_NONE;
239 }
240 }
241
dma350_set_trigout_nonsecure(struct dma350_dev_t * dev,uint8_t trigger)242 enum dma350_error_t dma350_set_trigout_nonsecure(struct dma350_dev_t *dev,
243 uint8_t trigger)
244 {
245 if (!dma350_is_init(dev)) {
246 return DMA350_ERR_NOT_INIT;
247 }
248
249 if(trigger >= 32) {
250 return DMA350_ERR_INVALID_PARAM;
251 }
252
253 dev->cfg->dma_sec_cfg->SCFG_TRIGOUTSEC0 =
254 dev->cfg->dma_sec_cfg->SCFG_TRIGOUTSEC0 | (0x1UL << trigger);
255 if (dev->cfg->dma_sec_cfg->SCFG_TRIGOUTSEC0 & (0x1UL << trigger)) {
256 return DMA350_ERR_NONE;
257 } else {
258 return DMA350_ERR_CANNOT_SET_NOW;
259 }
260 }
261