1 /*
2 * Copyright 2017-2021 NXP
3 * All rights reserved.
4 *
5 * SPDX-License-Identifier: BSD-3-Clause
6 */
7
8 #ifndef _FSL_RDC_H_
9 #define _FSL_RDC_H_
10
11 #include "fsl_common.h"
12
13 /*!
14 * @addtogroup rdc
15 * @{
16 */
17
18 /******************************************************************************
19 * Definitions
20 *****************************************************************************/
21 #define FSL_RDC_DRIVER_VERSION (MAKE_VERSION(2, 2, 0))
22
23 #define RDC_ACCESS_POLICY(domainID, policy) (uint16_t)((uint16_t)(policy) << ((domainID)*2U))
24
25 /*!
26 * @brief RDC hardware configuration.
27 */
28 typedef struct _rdc_hardware_config
29 {
30 uint32_t domainNumber : 4; /*!< Number of domains. */
31 uint32_t masterNumber : 8; /*!< Number of bus masters. */
32 uint32_t periphNumber : 8; /*!< Number of peripherals. */
33 uint32_t memNumber : 8; /*!< Number of memory regions. */
34 uint32_t : 4;
35 } rdc_hardware_config_t;
36
37 /*!
38 * @brief RDC interrupts
39 */
40 enum _rdc_interrupts
41 {
42 kRDC_RestoreCompleteInterrupt = RDC_INTCTRL_RCI_EN_MASK,
43 /*!< Interrupt generated when the RDC has completed restoring state to a recently re-powered memory regions. */
44 };
45
46 /*!
47 * @brief RDC status
48 */
49 enum _rdc_flags
50 {
51 kRDC_PowerDownDomainOn = RDC_STAT_PDS_MASK, /*!< Power down domain is ON. */
52 };
53
54 /*!
55 * @brief Master domain assignment.
56 */
57 typedef struct _rdc_domain_assignment
58 {
59 uint32_t domainId : 2U; /*!< Domain ID. */
60 uint32_t : 29U; /*!< Reserved. */
61 uint32_t lock : 1U; /*!< Lock the domain assignment. */
62 } rdc_domain_assignment_t;
63
64 /*!
65 * @brief Access permission policy.
66 */
67 enum _rdc_access_policy
68 {
69 kRDC_NoAccess = 0, /*!< Could not read or write. */
70 kRDC_WriteOnly = 1, /*!< Write only. */
71 kRDC_ReadOnly = 2, /*!< Read only. */
72 kRDC_ReadWrite = 3, /*!< Read and write. */
73 };
74
75 /*!
76 * @brief Peripheral domain access permission configuration.
77 */
78 typedef struct _rdc_periph_access_config
79 {
80 rdc_periph_t periph; /*!< Peripheral name. */
81 bool lock; /*!< Lock the permission until reset. */
82 bool enableSema; /*!< Enable semaphore or not, when enabled, master should
83 call @ref RDC_SEMA42_Lock to lock the semaphore gate
84 accordingly before access the peripheral. */
85 uint16_t policy; /*!< Access policy. */
86 } rdc_periph_access_config_t;
87
88 /*!
89 * @brief Memory region domain access control configuration.
90 *
91 * Note that when setting the @ref baseAddress and @ref endAddress,
92 * should be aligned to the region resolution, see rdc_mem_t
93 * definitions.
94 */
95 typedef struct _rdc_mem_access_config
96 {
97 rdc_mem_t mem; /*!< Memory region descriptor name. */
98
99 bool lock; /*!< Lock the configuration. */
100 uint64_t baseAddress; /*!< Start address of the memory region. */
101 uint64_t endAddress; /*!< End address of the memory region. */
102 uint16_t policy; /*!< Access policy. */
103 } rdc_mem_access_config_t;
104
105 /*!
106 * @brief Memory region access violation status.
107 */
108 typedef struct _rdc_mem_status
109 {
110 bool hasViolation; /*!< Violating happens or not. */
111 uint8_t domainID; /*!< Violating Domain ID. */
112 uint64_t address; /*!< Violating Address. */
113 } rdc_mem_status_t;
114
115 /*******************************************************************************
116 * API
117 ******************************************************************************/
118
119 #if defined(__cplusplus)
120 extern "C" {
121 #endif
122
123 /*!
124 * @brief Initializes the RDC module.
125 *
126 * This function enables the RDC clock.
127 *
128 * @param base RDC peripheral base address.
129 */
130 void RDC_Init(RDC_Type *base);
131
132 /*!
133 * @brief De-initializes the RDC module.
134 *
135 * This function disables the RDC clock.
136 *
137 * @param base RDC peripheral base address.
138 */
139 void RDC_Deinit(RDC_Type *base);
140
141 /*!
142 * @brief Gets the RDC hardware configuration.
143 *
144 * This function gets the RDC hardware configurations, including number of bus
145 * masters, number of domains, number of memory regions and number of peripherals.
146 *
147 * @param base RDC peripheral base address.
148 * @param config Pointer to the structure to get the configuration.
149 */
150 void RDC_GetHardwareConfig(RDC_Type *base, rdc_hardware_config_t *config);
151
152 /*!
153 * @brief Enable interrupts.
154 *
155 * @param base RDC peripheral base address.
156 * @param mask Interrupts to enable, it is OR'ed value of enum @ref _rdc_interrupts.
157 */
RDC_EnableInterrupts(RDC_Type * base,uint32_t mask)158 static inline void RDC_EnableInterrupts(RDC_Type *base, uint32_t mask)
159 {
160 base->INTCTRL |= mask;
161 }
162
163 /*!
164 * @brief Disable interrupts.
165 *
166 * @param base RDC peripheral base address.
167 * @param mask Interrupts to disable, it is OR'ed value of enum @ref _rdc_interrupts.
168 */
RDC_DisableInterrupts(RDC_Type * base,uint32_t mask)169 static inline void RDC_DisableInterrupts(RDC_Type *base, uint32_t mask)
170 {
171 base->INTCTRL &= ~mask;
172 }
173
174 /*!
175 * @brief Get the interrupt pending status.
176 *
177 * @param base RDC peripheral base address.
178 * @return Interrupts pending status, it is OR'ed value of enum @ref _rdc_interrupts.
179 */
RDC_GetInterruptStatus(RDC_Type * base)180 static inline uint32_t RDC_GetInterruptStatus(RDC_Type *base)
181 {
182 return base->INTSTAT;
183 }
184
185 /*!
186 * @brief Clear interrupt pending status.
187 *
188 * @param base RDC peripheral base address.
189 * @param mask Status to clear, it is OR'ed value of enum @ref _rdc_interrupts.
190 */
RDC_ClearInterruptStatus(RDC_Type * base,uint32_t mask)191 static inline void RDC_ClearInterruptStatus(RDC_Type *base, uint32_t mask)
192 {
193 base->INTSTAT = mask;
194 }
195
196 /*!
197 * @brief Get RDC status.
198 *
199 * @param base RDC peripheral base address.
200 * @return mask RDC status, it is OR'ed value of enum @ref _rdc_flags.
201 */
RDC_GetStatus(RDC_Type * base)202 static inline uint32_t RDC_GetStatus(RDC_Type *base)
203 {
204 return base->STAT;
205 }
206
207 /*!
208 * @brief Clear RDC status.
209 *
210 * @param base RDC peripheral base address.
211 * @param mask RDC status to clear, it is OR'ed value of enum @ref _rdc_flags.
212 */
RDC_ClearStatus(RDC_Type * base,uint32_t mask)213 static inline void RDC_ClearStatus(RDC_Type *base, uint32_t mask)
214 {
215 base->STAT = mask;
216 }
217
218 /*!
219 * @brief Set master domain assignment
220 *
221 * @param base RDC peripheral base address.
222 * @param master Which master to set.
223 * @param domainAssignment Pointer to the assignment.
224 */
225 void RDC_SetMasterDomainAssignment(RDC_Type *base,
226 rdc_master_t master,
227 const rdc_domain_assignment_t *domainAssignment);
228
229 /*!
230 * @brief Get default master domain assignment
231 *
232 * The default configuration is:
233 * @code
234 assignment->domainId = 0U;
235 assignment->lock = 0U;
236 @endcode
237 *
238 * @param domainAssignment Pointer to the assignment.
239 */
240 void RDC_GetDefaultMasterDomainAssignment(rdc_domain_assignment_t *domainAssignment);
241
242 /*!
243 * @brief Lock master domain assignment
244 *
245 * Once locked, it could not be unlocked until next reset.
246 *
247 * @param base RDC peripheral base address.
248 * @param master Which master to lock.
249 */
RDC_LockMasterDomainAssignment(RDC_Type * base,rdc_master_t master)250 static inline void RDC_LockMasterDomainAssignment(RDC_Type *base, rdc_master_t master)
251 {
252 assert((uint32_t)master < RDC_MDA_COUNT);
253
254 base->MDA[master] |= RDC_MDA_LCK_MASK;
255 __DSB();
256 }
257
258 /*!
259 * @brief Set peripheral access policy.
260 *
261 * @param base RDC peripheral base address.
262 * @param config Pointer to the policy configuration.
263 */
264 void RDC_SetPeriphAccessConfig(RDC_Type *base, const rdc_periph_access_config_t *config);
265
266 /*!
267 * @brief Get default peripheral access policy.
268 *
269 * The default configuration is:
270 * @code
271 config->lock = false;
272 config->enableSema = false;
273 config->policy = RDC_ACCESS_POLICY(0, kRDC_ReadWrite) |
274 RDC_ACCESS_POLICY(1, kRDC_ReadWrite) |
275 RDC_ACCESS_POLICY(2, kRDC_ReadWrite) |
276 RDC_ACCESS_POLICY(3, kRDC_ReadWrite);
277 @endcode
278 *
279 * @param config Pointer to the policy configuration.
280 */
281 void RDC_GetDefaultPeriphAccessConfig(rdc_periph_access_config_t *config);
282
283 /*!
284 * @brief Lock peripheral access policy configuration.
285 *
286 * Once locked, it could not be unlocked until reset.
287 *
288 * @param base RDC peripheral base address.
289 * @param periph Which peripheral to lock.
290 */
RDC_LockPeriphAccessConfig(RDC_Type * base,rdc_periph_t periph)291 static inline void RDC_LockPeriphAccessConfig(RDC_Type *base, rdc_periph_t periph)
292 {
293 assert((uint32_t)periph < RDC_PDAP_COUNT);
294
295 base->PDAP[periph] |= RDC_PDAP_LCK_MASK;
296 __DSB();
297 }
298
299 /*!
300 * @brief Get the peripheral access policy for specific domain.
301 *
302 * @param base RDC peripheral base address.
303 * @param periph Which peripheral to get.
304 * @param domainId Get policy for which domain.
305 * @return Access policy, see @ref _rdc_access_policy.
306 */
RDC_GetPeriphAccessPolicy(RDC_Type * base,rdc_periph_t periph,uint8_t domainId)307 static inline uint8_t RDC_GetPeriphAccessPolicy(RDC_Type *base, rdc_periph_t periph, uint8_t domainId)
308 {
309 assert((uint32_t)periph < RDC_PDAP_COUNT);
310
311 return (uint8_t)((base->PDAP[periph] >> (domainId * 2U)) & 0x03U);
312 }
313
314 /*!
315 * @brief Set memory region access policy.
316 *
317 * Note that when setting the baseAddress and endAddress in @p config,
318 * should be aligned to the region resolution, see rdc_mem_t
319 * definitions.
320 *
321 * @param base RDC peripheral base address.
322 * @param config Pointer to the policy configuration.
323 */
324 void RDC_SetMemAccessConfig(RDC_Type *base, const rdc_mem_access_config_t *config);
325
326 /*!
327 * @brief Get default memory region access policy.
328 *
329 * The default configuration is:
330 * @code
331 config->lock = false;
332 config->baseAddress = 0;
333 config->endAddress = 0;
334 config->policy = RDC_ACCESS_POLICY(0, kRDC_ReadWrite) |
335 RDC_ACCESS_POLICY(1, kRDC_ReadWrite) |
336 RDC_ACCESS_POLICY(2, kRDC_ReadWrite) |
337 RDC_ACCESS_POLICY(3, kRDC_ReadWrite);
338 @endcode
339 *
340 * @param config Pointer to the policy configuration.
341 */
342 void RDC_GetDefaultMemAccessConfig(rdc_mem_access_config_t *config);
343
344 /*!
345 * @brief Lock memory access policy configuration.
346 *
347 * Once locked, it could not be unlocked until reset. After locked, you can
348 * only call @ref RDC_SetMemAccessValid to enable the configuration, but can not
349 * disable it or change other settings.
350 *
351 * @param base RDC peripheral base address.
352 * @param mem Which memory region to lock.
353 */
RDC_LockMemAccessConfig(RDC_Type * base,rdc_mem_t mem)354 static inline void RDC_LockMemAccessConfig(RDC_Type *base, rdc_mem_t mem)
355 {
356 assert((uint32_t)mem < RDC_MRC_COUNT);
357
358 base->MR[mem].MRC |= RDC_MRC_LCK_MASK;
359 __DSB();
360 }
361
362 /*!
363 * @brief Enable or disable memory access policy configuration.
364 *
365 * @param base RDC peripheral base address.
366 * @param mem Which memory region to operate.
367 * @param valid Pass in true to valid, false to invalid.
368 */
RDC_SetMemAccessValid(RDC_Type * base,rdc_mem_t mem,bool valid)369 static inline void RDC_SetMemAccessValid(RDC_Type *base, rdc_mem_t mem, bool valid)
370 {
371 assert((uint32_t)mem < RDC_MRC_COUNT);
372
373 if (valid)
374 {
375 base->MR[mem].MRC |= RDC_MRC_ENA_MASK;
376 }
377 else
378 {
379 base->MR[mem].MRC &= ~RDC_MRC_ENA_MASK;
380 }
381 __DSB();
382 }
383
384 /*!
385 * @brief Get the memory region violation status.
386 *
387 * The first access violation is captured. Subsequent violations are ignored
388 * until the status register is cleared. Contents are cleared upon reading the
389 * register. Clearing of contents occurs only when the status is read by the
390 * memory region's associated domain ID(s).
391 *
392 * @param base RDC peripheral base address.
393 * @param mem Which memory region to get.
394 * @param status The returned status.
395 */
396 void RDC_GetMemViolationStatus(RDC_Type *base, rdc_mem_t mem, rdc_mem_status_t *status);
397
398 /*!
399 * @brief Clear the memory region violation flag.
400 *
401 * @param base RDC peripheral base address.
402 * @param mem Which memory region to clear.
403 */
RDC_ClearMemViolationFlag(RDC_Type * base,rdc_mem_t mem)404 static inline void RDC_ClearMemViolationFlag(RDC_Type *base, rdc_mem_t mem)
405 {
406 assert((uint32_t)mem < RDC_MRC_COUNT);
407
408 base->MR[mem].MRVS = RDC_MRVS_AD_MASK;
409 }
410
411 /*!
412 * @brief Get the memory region access policy for specific domain.
413 *
414 * @param base RDC peripheral base address.
415 * @param mem Which memory region to get.
416 * @param domainId Get policy for which domain.
417 * @return Access policy, see @ref _rdc_access_policy.
418 */
RDC_GetMemAccessPolicy(RDC_Type * base,rdc_mem_t mem,uint8_t domainId)419 static inline uint8_t RDC_GetMemAccessPolicy(RDC_Type *base, rdc_mem_t mem, uint8_t domainId)
420 {
421 assert((uint32_t)mem < RDC_MRC_COUNT);
422
423 return (uint8_t)((base->MR[mem].MRC >> (domainId * 2U)) & 0x03U);
424 }
425
426 /*!
427 * @brief Gets the domain ID of the current bus master.
428 *
429 * This function returns the domain ID of the current bus master.
430 *
431 * @param base RDC peripheral base address.
432 * @return Domain ID of current bus master.
433 */
RDC_GetCurrentMasterDomainId(RDC_Type * base)434 static inline uint8_t RDC_GetCurrentMasterDomainId(RDC_Type *base)
435 {
436 return (uint8_t)((base->STAT & RDC_STAT_DID_MASK) >> RDC_STAT_DID_SHIFT);
437 }
438
439 #if defined(__cplusplus)
440 }
441 #endif
442
443 /*!
444 * @}
445 */
446
447 #endif /* _FSL_RDC_H_ */
448