Back to home page

LXR

 
 

    


File indexing completed on 2025-05-11 08:23:01

0001 /*
0002  * Copyright 2017-2021 NXP
0003  * All rights reserved.
0004  *
0005  * SPDX-License-Identifier: BSD-3-Clause
0006  */
0007 
0008 #ifndef _FSL_RDC_H_
0009 #define _FSL_RDC_H_
0010 
0011 #include "fsl_common.h"
0012 
0013 /*!
0014  * @addtogroup rdc
0015  * @{
0016  */
0017 
0018 /******************************************************************************
0019  * Definitions
0020  *****************************************************************************/
0021 #define FSL_RDC_DRIVER_VERSION (MAKE_VERSION(2, 2, 0))
0022 
0023 #define RDC_ACCESS_POLICY(domainID, policy) (uint16_t)((uint16_t)(policy) << ((domainID)*2U))
0024 
0025 /*!
0026  * @brief RDC hardware configuration.
0027  */
0028 typedef struct _rdc_hardware_config
0029 {
0030     uint32_t domainNumber : 4; /*!< Number of domains.        */
0031     uint32_t masterNumber : 8; /*!< Number of bus masters.    */
0032     uint32_t periphNumber : 8; /*!< Number of peripherals.    */
0033     uint32_t memNumber : 8;    /*!< Number of memory regions. */
0034     uint32_t : 4;
0035 } rdc_hardware_config_t;
0036 
0037 /*!
0038  * @brief RDC interrupts
0039  */
0040 enum _rdc_interrupts
0041 {
0042     kRDC_RestoreCompleteInterrupt = RDC_INTCTRL_RCI_EN_MASK,
0043     /*!< Interrupt generated when the RDC has completed restoring state to a recently re-powered memory regions. */
0044 };
0045 
0046 /*!
0047  * @brief RDC status
0048  */
0049 enum _rdc_flags
0050 {
0051     kRDC_PowerDownDomainOn = RDC_STAT_PDS_MASK, /*!< Power down domain is ON. */
0052 };
0053 
0054 /*!
0055  * @brief Master domain assignment.
0056  */
0057 typedef struct _rdc_domain_assignment
0058 {
0059     uint32_t domainId : 2U; /*!< Domain ID.                  */
0060     uint32_t : 29U;         /*!< Reserved.                   */
0061     uint32_t lock : 1U;     /*!< Lock the domain assignment. */
0062 } rdc_domain_assignment_t;
0063 
0064 /*!
0065  * @brief Access permission policy.
0066  */
0067 enum _rdc_access_policy
0068 {
0069     kRDC_NoAccess  = 0, /*!< Could not read or write. */
0070     kRDC_WriteOnly = 1, /*!< Write only. */
0071     kRDC_ReadOnly  = 2, /*!< Read only. */
0072     kRDC_ReadWrite = 3, /*!< Read and write. */
0073 };
0074 
0075 /*!
0076  * @brief Peripheral domain access permission configuration.
0077  */
0078 typedef struct _rdc_periph_access_config
0079 {
0080     rdc_periph_t periph; /*!< Peripheral name.                 */
0081     bool lock;           /*!< Lock the permission until reset. */
0082     bool enableSema;     /*!< Enable semaphore or not, when enabled, master should
0083                               call @ref RDC_SEMA42_Lock to lock the semaphore gate
0084                               accordingly before access the peripheral. */
0085     uint16_t policy;     /*!< Access policy.                   */
0086 } rdc_periph_access_config_t;
0087 
0088 /*!
0089  * @brief Memory region domain access control configuration.
0090  *
0091  * Note that when setting the @ref baseAddress and @ref endAddress,
0092  * should be aligned to the region resolution, see rdc_mem_t
0093  * definitions.
0094  */
0095 typedef struct _rdc_mem_access_config
0096 {
0097     rdc_mem_t mem; /*!< Memory region descriptor name. */
0098 
0099     bool lock;            /*!< Lock the configuration. */
0100     uint64_t baseAddress; /*!< Start address of the memory region. */
0101     uint64_t endAddress;  /*!< End address of the memory region.   */
0102     uint16_t policy;      /*!< Access policy.                      */
0103 } rdc_mem_access_config_t;
0104 
0105 /*!
0106  * @brief Memory region access violation status.
0107  */
0108 typedef struct _rdc_mem_status
0109 {
0110     bool hasViolation; /*!< Violating happens or not. */
0111     uint8_t domainID;  /*!< Violating Domain ID. */
0112     uint64_t address;  /*!< Violating Address. */
0113 } rdc_mem_status_t;
0114 
0115 /*******************************************************************************
0116  * API
0117  ******************************************************************************/
0118 
0119 #if defined(__cplusplus)
0120 extern "C" {
0121 #endif
0122 
0123 /*!
0124  * @brief Initializes the RDC module.
0125  *
0126  * This function enables the RDC clock.
0127  *
0128  * @param base RDC peripheral base address.
0129  */
0130 void RDC_Init(RDC_Type *base);
0131 
0132 /*!
0133  * @brief De-initializes the RDC module.
0134  *
0135  * This function disables the RDC clock.
0136  *
0137  * @param base RDC peripheral base address.
0138  */
0139 void RDC_Deinit(RDC_Type *base);
0140 
0141 /*!
0142  * @brief Gets the RDC hardware configuration.
0143  *
0144  * This function gets the RDC hardware configurations, including number of bus
0145  * masters, number of domains, number of memory regions and number of peripherals.
0146  *
0147  * @param base RDC peripheral base address.
0148  * @param config Pointer to the structure to get the configuration.
0149  */
0150 void RDC_GetHardwareConfig(RDC_Type *base, rdc_hardware_config_t *config);
0151 
0152 /*!
0153  * @brief Enable interrupts.
0154  *
0155  * @param base RDC peripheral base address.
0156  * @param mask Interrupts to enable, it is OR'ed value of enum @ref _rdc_interrupts.
0157  */
0158 static inline void RDC_EnableInterrupts(RDC_Type *base, uint32_t mask)
0159 {
0160     base->INTCTRL |= mask;
0161 }
0162 
0163 /*!
0164  * @brief Disable interrupts.
0165  *
0166  * @param base RDC peripheral base address.
0167  * @param mask Interrupts to disable, it is OR'ed value of enum @ref _rdc_interrupts.
0168  */
0169 static inline void RDC_DisableInterrupts(RDC_Type *base, uint32_t mask)
0170 {
0171     base->INTCTRL &= ~mask;
0172 }
0173 
0174 /*!
0175  * @brief Get the interrupt pending status.
0176  *
0177  * @param base RDC peripheral base address.
0178  * @return Interrupts pending status, it is OR'ed value of enum @ref _rdc_interrupts.
0179  */
0180 static inline uint32_t RDC_GetInterruptStatus(RDC_Type *base)
0181 {
0182     return base->INTSTAT;
0183 }
0184 
0185 /*!
0186  * @brief Clear interrupt pending status.
0187  *
0188  * @param base RDC peripheral base address.
0189  * @param mask Status to clear, it is OR'ed value of enum @ref _rdc_interrupts.
0190  */
0191 static inline void RDC_ClearInterruptStatus(RDC_Type *base, uint32_t mask)
0192 {
0193     base->INTSTAT = mask;
0194 }
0195 
0196 /*!
0197  * @brief Get RDC status.
0198  *
0199  * @param base RDC peripheral base address.
0200  * @return mask RDC status, it is OR'ed value of enum @ref _rdc_flags.
0201  */
0202 static inline uint32_t RDC_GetStatus(RDC_Type *base)
0203 {
0204     return base->STAT;
0205 }
0206 
0207 /*!
0208  * @brief Clear RDC status.
0209  *
0210  * @param base RDC peripheral base address.
0211  * @param mask RDC status to clear, it is OR'ed value of enum @ref _rdc_flags.
0212  */
0213 static inline void RDC_ClearStatus(RDC_Type *base, uint32_t mask)
0214 {
0215     base->STAT = mask;
0216 }
0217 
0218 /*!
0219  * @brief Set master domain assignment
0220  *
0221  * @param base RDC peripheral base address.
0222  * @param master Which master to set.
0223  * @param domainAssignment Pointer to the assignment.
0224  */
0225 void RDC_SetMasterDomainAssignment(RDC_Type *base,
0226                                    rdc_master_t master,
0227                                    const rdc_domain_assignment_t *domainAssignment);
0228 
0229 /*!
0230  * @brief Get default master domain assignment
0231  *
0232  * The default configuration is:
0233  * @code
0234    assignment->domainId = 0U;
0235    assignment->lock = 0U;
0236    @endcode
0237  *
0238  * @param domainAssignment Pointer to the assignment.
0239  */
0240 void RDC_GetDefaultMasterDomainAssignment(rdc_domain_assignment_t *domainAssignment);
0241 
0242 /*!
0243  * @brief Lock master domain assignment
0244  *
0245  * Once locked, it could not be unlocked until next reset.
0246  *
0247  * @param base RDC peripheral base address.
0248  * @param master Which master to lock.
0249  */
0250 static inline void RDC_LockMasterDomainAssignment(RDC_Type *base, rdc_master_t master)
0251 {
0252     assert((uint32_t)master < RDC_MDA_COUNT);
0253 
0254     base->MDA[master] |= RDC_MDA_LCK_MASK;
0255     __DSB();
0256 }
0257 
0258 /*!
0259  * @brief Set peripheral access policy.
0260  *
0261  * @param base RDC peripheral base address.
0262  * @param config Pointer to the policy configuration.
0263  */
0264 void RDC_SetPeriphAccessConfig(RDC_Type *base, const rdc_periph_access_config_t *config);
0265 
0266 /*!
0267  * @brief Get default peripheral access policy.
0268  *
0269  * The default configuration is:
0270  * @code
0271     config->lock = false;
0272     config->enableSema = false;
0273     config->policy = RDC_ACCESS_POLICY(0, kRDC_ReadWrite) |
0274                      RDC_ACCESS_POLICY(1, kRDC_ReadWrite) |
0275                      RDC_ACCESS_POLICY(2, kRDC_ReadWrite) |
0276                      RDC_ACCESS_POLICY(3, kRDC_ReadWrite);
0277    @endcode
0278  *
0279  * @param config Pointer to the policy configuration.
0280  */
0281 void RDC_GetDefaultPeriphAccessConfig(rdc_periph_access_config_t *config);
0282 
0283 /*!
0284  * @brief Lock peripheral access policy configuration.
0285  *
0286  * Once locked, it could not be unlocked until reset.
0287  *
0288  * @param base RDC peripheral base address.
0289  * @param periph Which peripheral to lock.
0290  */
0291 static inline void RDC_LockPeriphAccessConfig(RDC_Type *base, rdc_periph_t periph)
0292 {
0293     assert((uint32_t)periph < RDC_PDAP_COUNT);
0294 
0295     base->PDAP[periph] |= RDC_PDAP_LCK_MASK;
0296     __DSB();
0297 }
0298 
0299 /*!
0300  * @brief Get the peripheral access policy for specific domain.
0301  *
0302  * @param base RDC peripheral base address.
0303  * @param periph Which peripheral to get.
0304  * @param domainId Get policy for which domain.
0305  * @return Access policy, see @ref _rdc_access_policy.
0306  */
0307 static inline uint8_t RDC_GetPeriphAccessPolicy(RDC_Type *base, rdc_periph_t periph, uint8_t domainId)
0308 {
0309     assert((uint32_t)periph < RDC_PDAP_COUNT);
0310 
0311     return (uint8_t)((base->PDAP[periph] >> (domainId * 2U)) & 0x03U);
0312 }
0313 
0314 /*!
0315  * @brief Set memory region access policy.
0316  *
0317  * Note that when setting the baseAddress and endAddress in @p config,
0318  * should be aligned to the region resolution, see rdc_mem_t
0319  * definitions.
0320  *
0321  * @param base RDC peripheral base address.
0322  * @param config Pointer to the policy configuration.
0323  */
0324 void RDC_SetMemAccessConfig(RDC_Type *base, const rdc_mem_access_config_t *config);
0325 
0326 /*!
0327  * @brief Get default memory region access policy.
0328  *
0329  * The default configuration is:
0330  * @code
0331     config->lock = false;
0332     config->baseAddress = 0;
0333     config->endAddress = 0;
0334     config->policy = RDC_ACCESS_POLICY(0, kRDC_ReadWrite) |
0335                      RDC_ACCESS_POLICY(1, kRDC_ReadWrite) |
0336                      RDC_ACCESS_POLICY(2, kRDC_ReadWrite) |
0337                      RDC_ACCESS_POLICY(3, kRDC_ReadWrite);
0338    @endcode
0339  *
0340  * @param config Pointer to the policy configuration.
0341  */
0342 void RDC_GetDefaultMemAccessConfig(rdc_mem_access_config_t *config);
0343 
0344 /*!
0345  * @brief Lock memory access policy configuration.
0346  *
0347  * Once locked, it could not be unlocked until reset. After locked, you can
0348  * only call @ref RDC_SetMemAccessValid to enable the configuration, but can not
0349  * disable it or change other settings.
0350  *
0351  * @param base RDC peripheral base address.
0352  * @param mem Which memory region to lock.
0353  */
0354 static inline void RDC_LockMemAccessConfig(RDC_Type *base, rdc_mem_t mem)
0355 {
0356     assert((uint32_t)mem < RDC_MRC_COUNT);
0357 
0358     base->MR[mem].MRC |= RDC_MRC_LCK_MASK;
0359     __DSB();
0360 }
0361 
0362 /*!
0363  * @brief Enable or disable memory access policy configuration.
0364  *
0365  * @param base RDC peripheral base address.
0366  * @param mem Which memory region to operate.
0367  * @param valid Pass in true to valid, false to invalid.
0368  */
0369 static inline void RDC_SetMemAccessValid(RDC_Type *base, rdc_mem_t mem, bool valid)
0370 {
0371     assert((uint32_t)mem < RDC_MRC_COUNT);
0372 
0373     if (valid)
0374     {
0375         base->MR[mem].MRC |= RDC_MRC_ENA_MASK;
0376     }
0377     else
0378     {
0379         base->MR[mem].MRC &= ~RDC_MRC_ENA_MASK;
0380     }
0381     __DSB();
0382 }
0383 
0384 /*!
0385  * @brief Get the memory region violation status.
0386  *
0387  * The first access violation is captured. Subsequent violations are ignored
0388  * until the status register is cleared. Contents are cleared upon reading the
0389  * register. Clearing of contents occurs only when the status is read by the
0390  * memory region's associated domain ID(s).
0391  *
0392  * @param base RDC peripheral base address.
0393  * @param mem Which memory region to get.
0394  * @param status The returned status.
0395  */
0396 void RDC_GetMemViolationStatus(RDC_Type *base, rdc_mem_t mem, rdc_mem_status_t *status);
0397 
0398 /*!
0399  * @brief Clear the memory region violation flag.
0400  *
0401  * @param base RDC peripheral base address.
0402  * @param mem Which memory region to clear.
0403  */
0404 static inline void RDC_ClearMemViolationFlag(RDC_Type *base, rdc_mem_t mem)
0405 {
0406     assert((uint32_t)mem < RDC_MRC_COUNT);
0407 
0408     base->MR[mem].MRVS = RDC_MRVS_AD_MASK;
0409 }
0410 
0411 /*!
0412  * @brief Get the memory region access policy for specific domain.
0413  *
0414  * @param base RDC peripheral base address.
0415  * @param mem Which memory region to get.
0416  * @param domainId Get policy for which domain.
0417  * @return Access policy, see @ref _rdc_access_policy.
0418  */
0419 static inline uint8_t RDC_GetMemAccessPolicy(RDC_Type *base, rdc_mem_t mem, uint8_t domainId)
0420 {
0421     assert((uint32_t)mem < RDC_MRC_COUNT);
0422 
0423     return (uint8_t)((base->MR[mem].MRC >> (domainId * 2U)) & 0x03U);
0424 }
0425 
0426 /*!
0427  * @brief Gets the domain ID of the current bus master.
0428  *
0429  * This function returns the domain ID of the current bus master.
0430  *
0431  * @param base RDC peripheral base address.
0432  * @return Domain ID of current bus master.
0433  */
0434 static inline uint8_t RDC_GetCurrentMasterDomainId(RDC_Type *base)
0435 {
0436     return (uint8_t)((base->STAT & RDC_STAT_DID_MASK) >> RDC_STAT_DID_SHIFT);
0437 }
0438 
0439 #if defined(__cplusplus)
0440 }
0441 #endif
0442 
0443 /*!
0444  * @}
0445  */
0446 
0447 #endif /* _FSL_RDC_H_ */