Back to home page

LXR

 
 

    


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

0001 /*
0002  * Copyright 2017-2020 NXP
0003  * All rights reserved.
0004  *
0005  * SPDX-License-Identifier: BSD-3-Clause
0006  */
0007 
0008 #include "fsl_rdc.h"
0009 
0010 /******************************************************************************
0011  * Definitions
0012  *****************************************************************************/
0013 
0014 /* Component ID definition, used by tools. */
0015 #ifndef FSL_COMPONENT_ID
0016 #define FSL_COMPONENT_ID "platform.drivers.rdc"
0017 #endif
0018 
0019 typedef union
0020 {
0021     rdc_domain_assignment_t _mda;
0022     uint32_t _u32;
0023 } rdc_mda_reg_t;
0024 
0025 typedef union
0026 {
0027     rdc_hardware_config_t _vir;
0028     uint32_t _u32;
0029 } rdc_vir_reg_t;
0030 
0031 /*******************************************************************************
0032  * Prototypes
0033  ******************************************************************************/
0034 
0035 /*!
0036  * @brief Get instance number for RDC module.
0037  *
0038  * @param base RDC peripheral base address.
0039  */
0040 uint32_t RDC_GetInstance(RDC_Type *base);
0041 
0042 /*******************************************************************************
0043  * Variables
0044  ******************************************************************************/
0045 
0046 /*! @brief Pointers to rdc bases for each instance. */
0047 static RDC_Type *const s_rdcBases[] = RDC_BASE_PTRS;
0048 
0049 #if !(defined(FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) && FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL)
0050 /*! @brief Pointers to rdc clocks for each instance. */
0051 static const clock_ip_name_t s_rdcClocks[] = RDC_CLOCKS;
0052 #endif /* FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL */
0053 
0054 /******************************************************************************
0055  * CODE
0056  *****************************************************************************/
0057 
0058 uint32_t RDC_GetInstance(RDC_Type *base)
0059 {
0060     uint32_t instance;
0061 
0062     /* Find the instance index from base address mappings. */
0063     for (instance = 0; instance < ARRAY_SIZE(s_rdcBases); instance++)
0064     {
0065         if (s_rdcBases[instance] == base)
0066         {
0067             break;
0068         }
0069     }
0070 
0071     assert(instance < ARRAY_SIZE(s_rdcBases));
0072 
0073     return instance;
0074 }
0075 
0076 /*!
0077  * brief Initializes the RDC module.
0078  *
0079  * This function enables the RDC clock.
0080  *
0081  * param base RDC peripheral base address.
0082  */
0083 void RDC_Init(RDC_Type *base)
0084 {
0085 #if !(defined(FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) && FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL)
0086     CLOCK_EnableClock(s_rdcClocks[RDC_GetInstance(base)]);
0087 #endif /* FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL */
0088 }
0089 
0090 /*!
0091  * brief De-initializes the RDC module.
0092  *
0093  * This function disables the RDC clock.
0094  *
0095  * param base RDC peripheral base address.
0096  */
0097 void RDC_Deinit(RDC_Type *base)
0098 {
0099 #if !(defined(FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) && FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL)
0100     CLOCK_DisableClock(s_rdcClocks[RDC_GetInstance(base)]);
0101 #endif /* FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL */
0102 }
0103 
0104 /*!
0105  * brief Gets the RDC hardware configuration.
0106  *
0107  * This function gets the RDC hardware configurations, including number of bus
0108  * masters, number of domains, number of memory regions and number of peripherals.
0109  *
0110  * param base RDC peripheral base address.
0111  * param config Pointer to the structure to get the configuration.
0112  */
0113 void RDC_GetHardwareConfig(RDC_Type *base, rdc_hardware_config_t *config)
0114 {
0115     assert(NULL != config);
0116 
0117     rdc_vir_reg_t vir;
0118     vir._u32 = base->VIR;
0119 
0120     *config = vir._vir;
0121 }
0122 
0123 /*!
0124  * brief Set master domain assignment
0125  *
0126  * param base RDC peripheral base address.
0127  * param master Which master to set.
0128  * param domainAssignment Pointer to the assignment.
0129  */
0130 void RDC_SetMasterDomainAssignment(RDC_Type *base, rdc_master_t master, const rdc_domain_assignment_t *domainAssignment)
0131 {
0132     assert((uint32_t)master < RDC_MDA_COUNT);
0133 
0134     rdc_mda_reg_t mda;
0135 
0136     mda._mda = *domainAssignment;
0137 
0138     base->MDA[master] = mda._u32;
0139 }
0140 
0141 /*!
0142  * brief Get default master domain assignment
0143  *
0144  * The default configuration is:
0145  * code
0146    assignment->domainId = 0U;
0147    assignment->lock = 0U;
0148    endcode
0149  *
0150  * param domainAssignment Pointer to the assignment.
0151  */
0152 void RDC_GetDefaultMasterDomainAssignment(rdc_domain_assignment_t *domainAssignment)
0153 {
0154     assert(NULL != domainAssignment);
0155 
0156     rdc_mda_reg_t mda;
0157     mda._u32 = 0U;
0158 
0159     *domainAssignment = mda._mda;
0160 }
0161 
0162 /*!
0163  * brief Set peripheral access policy.
0164  *
0165  * param base RDC peripheral base address.
0166  * param config Pointer to the policy configuration.
0167  */
0168 void RDC_SetPeriphAccessConfig(RDC_Type *base, const rdc_periph_access_config_t *config)
0169 {
0170     assert((uint32_t)config->periph < RDC_PDAP_COUNT);
0171 
0172     uint32_t periph  = (uint32_t)config->periph;
0173     uint32_t regPDAP = config->policy;
0174 
0175     if (config->lock)
0176     {
0177         regPDAP |= RDC_PDAP_LCK_MASK;
0178     }
0179 
0180     if (config->enableSema)
0181     {
0182         regPDAP |= RDC_PDAP_SREQ_MASK;
0183     }
0184 
0185     base->PDAP[periph] = regPDAP;
0186 
0187     __DSB();
0188 }
0189 
0190 /*!
0191  * brief Get default peripheral access policy.
0192  *
0193  * The default configuration is:
0194  * code
0195     config->lock = false;
0196     config->enableSema = false;
0197     config->policy = RDC_ACCESS_POLICY(0, kRDC_ReadWrite) |
0198                      RDC_ACCESS_POLICY(1, kRDC_ReadWrite) |
0199                      RDC_ACCESS_POLICY(2, kRDC_ReadWrite) |
0200                      RDC_ACCESS_POLICY(3, kRDC_ReadWrite);
0201    endcode
0202  *
0203  * param config Pointer to the policy configuration.
0204  */
0205 void RDC_GetDefaultPeriphAccessConfig(rdc_periph_access_config_t *config)
0206 {
0207     assert(NULL != config);
0208 
0209     /* Initializes the configure structure to zero. */
0210     (void)memset(config, 0, sizeof(*config));
0211 
0212     config->lock       = false;
0213     config->enableSema = false;
0214     config->policy     = RDC_ACCESS_POLICY(0U, kRDC_ReadWrite) | RDC_ACCESS_POLICY(1U, kRDC_ReadWrite) |
0215                      RDC_ACCESS_POLICY(2U, kRDC_ReadWrite) | RDC_ACCESS_POLICY(3U, kRDC_ReadWrite);
0216 }
0217 
0218 /*!
0219  * brief Set memory region access policy.
0220  *
0221  * Note that when setting the baseAddress and endAddress in p config,
0222  * should be aligned to the region resolution, see rdc_mem_t
0223  * definitions.
0224  *
0225  * param base RDC peripheral base address.
0226  * param config Pointer to the policy configuration.
0227  */
0228 void RDC_SetMemAccessConfig(RDC_Type *base, const rdc_mem_access_config_t *config)
0229 {
0230     assert((uint32_t)config->mem < RDC_MRC_COUNT);
0231 
0232     uint32_t mem = (uint32_t)config->mem;
0233     /* The configuration is enabled by default. */
0234     uint32_t regMRC = config->policy | RDC_MRC_ENA_MASK;
0235 
0236     if (config->lock)
0237     {
0238         regMRC |= RDC_MRC_LCK_MASK;
0239     }
0240 
0241 #if (defined(FSL_FEATURE_RDC_MEM_REGION_ADDR_SHIFT) && FSL_FEATURE_RDC_MEM_REGION_ADDR_SHIFT)
0242     base->MR[mem].MRSA = (uint32_t)(config->baseAddress >> (uint32_t)FSL_FEATURE_RDC_MEM_REGION_ADDR_SHIFT);
0243     base->MR[mem].MREA = (uint32_t)(config->endAddress >> (uint32_t)FSL_FEATURE_RDC_MEM_REGION_ADDR_SHIFT);
0244 #else
0245     base->MR[mem].MRSA = (uint32_t)config->baseAddress;
0246     base->MR[mem].MREA = (uint32_t)config->endAddress;
0247 #endif
0248     base->MR[mem].MRC = regMRC;
0249 
0250     __DSB();
0251 }
0252 
0253 /*!
0254  * brief Get default memory region access policy.
0255  *
0256  * The default configuration is:
0257  * code
0258     config->lock = false;
0259     config->baseAddress = 0;
0260     config->endAddress = 0;
0261     config->policy = RDC_ACCESS_POLICY(0, kRDC_ReadWrite) |
0262                      RDC_ACCESS_POLICY(1, kRDC_ReadWrite) |
0263                      RDC_ACCESS_POLICY(2, kRDC_ReadWrite) |
0264                      RDC_ACCESS_POLICY(3, kRDC_ReadWrite);
0265    endcode
0266  *
0267  * param config Pointer to the policy configuration.
0268  */
0269 void RDC_GetDefaultMemAccessConfig(rdc_mem_access_config_t *config)
0270 {
0271     assert(NULL != config);
0272 
0273     /* Initializes the configure structure to zero. */
0274     (void)memset(config, 0, sizeof(*config));
0275 
0276     config->lock        = false;
0277     config->baseAddress = 0;
0278     config->endAddress  = 0;
0279     config->policy      = RDC_ACCESS_POLICY(0U, kRDC_ReadWrite) | RDC_ACCESS_POLICY(1U, kRDC_ReadWrite) |
0280                      RDC_ACCESS_POLICY(2U, kRDC_ReadWrite) | RDC_ACCESS_POLICY(3U, kRDC_ReadWrite);
0281 }
0282 
0283 /*!
0284  * brief Get the memory region violation status.
0285  *
0286  * The first access violation is captured. Subsequent violations are ignored
0287  * until the status register is cleared. Contents are cleared upon reading the
0288  * register. Clearing of contents occurs only when the status is read by the
0289  * memory region's associated domain ID(s).
0290  *
0291  * param base RDC peripheral base address.
0292  * param mem Which memory region to get.
0293  * param status The returned status.
0294  */
0295 void RDC_GetMemViolationStatus(RDC_Type *base, rdc_mem_t mem, rdc_mem_status_t *status)
0296 {
0297     assert((uint32_t)mem < RDC_MRC_COUNT);
0298 
0299     uint32_t regMRVS = base->MR[mem].MRVS;
0300 
0301     status->hasViolation = ((regMRVS & RDC_MRVS_AD_MASK) != 0U);
0302     status->domainID     = (uint8_t)((regMRVS & RDC_MRVS_VDID_MASK) >> RDC_MRVS_VDID_SHIFT);
0303 #if (defined(FSL_FEATURE_RDC_MEM_REGION_ADDR_SHIFT) && FSL_FEATURE_RDC_MEM_REGION_ADDR_SHIFT)
0304     regMRVS &= RDC_MRVS_VADR_MASK;
0305     status->address = ((uint64_t)regMRVS) << (uint32_t)FSL_FEATURE_RDC_MEM_REGION_ADDR_SHIFT;
0306 #else
0307     regMRVS &= RDC_MRVS_VADR_MASK;
0308     status->address = (uint64_t)regMRVS;
0309 #endif
0310 }