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