diff options
Diffstat (limited to '')
-rw-r--r-- | bsps/arm/imxrt/mcux-sdk/drivers/rdc/fsl_rdc.c | 310 |
1 files changed, 310 insertions, 0 deletions
diff --git a/bsps/arm/imxrt/mcux-sdk/drivers/rdc/fsl_rdc.c b/bsps/arm/imxrt/mcux-sdk/drivers/rdc/fsl_rdc.c new file mode 100644 index 0000000000..816770dbd7 --- /dev/null +++ b/bsps/arm/imxrt/mcux-sdk/drivers/rdc/fsl_rdc.c @@ -0,0 +1,310 @@ +/* + * Copyright 2017-2020 NXP + * All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#include "fsl_rdc.h" + +/****************************************************************************** + * Definitions + *****************************************************************************/ + +/* Component ID definition, used by tools. */ +#ifndef FSL_COMPONENT_ID +#define FSL_COMPONENT_ID "platform.drivers.rdc" +#endif + +typedef union +{ + rdc_domain_assignment_t _mda; + uint32_t _u32; +} rdc_mda_reg_t; + +typedef union +{ + rdc_hardware_config_t _vir; + uint32_t _u32; +} rdc_vir_reg_t; + +/******************************************************************************* + * Prototypes + ******************************************************************************/ + +/*! + * @brief Get instance number for RDC module. + * + * @param base RDC peripheral base address. + */ +uint32_t RDC_GetInstance(RDC_Type *base); + +/******************************************************************************* + * Variables + ******************************************************************************/ + +/*! @brief Pointers to rdc bases for each instance. */ +static RDC_Type *const s_rdcBases[] = RDC_BASE_PTRS; + +#if !(defined(FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) && FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) +/*! @brief Pointers to rdc clocks for each instance. */ +static const clock_ip_name_t s_rdcClocks[] = RDC_CLOCKS; +#endif /* FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL */ + +/****************************************************************************** + * CODE + *****************************************************************************/ + +uint32_t RDC_GetInstance(RDC_Type *base) +{ + uint32_t instance; + + /* Find the instance index from base address mappings. */ + for (instance = 0; instance < ARRAY_SIZE(s_rdcBases); instance++) + { + if (s_rdcBases[instance] == base) + { + break; + } + } + + assert(instance < ARRAY_SIZE(s_rdcBases)); + + return instance; +} + +/*! + * brief Initializes the RDC module. + * + * This function enables the RDC clock. + * + * param base RDC peripheral base address. + */ +void RDC_Init(RDC_Type *base) +{ +#if !(defined(FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) && FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) + CLOCK_EnableClock(s_rdcClocks[RDC_GetInstance(base)]); +#endif /* FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL */ +} + +/*! + * brief De-initializes the RDC module. + * + * This function disables the RDC clock. + * + * param base RDC peripheral base address. + */ +void RDC_Deinit(RDC_Type *base) +{ +#if !(defined(FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) && FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) + CLOCK_DisableClock(s_rdcClocks[RDC_GetInstance(base)]); +#endif /* FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL */ +} + +/*! + * brief Gets the RDC hardware configuration. + * + * This function gets the RDC hardware configurations, including number of bus + * masters, number of domains, number of memory regions and number of peripherals. + * + * param base RDC peripheral base address. + * param config Pointer to the structure to get the configuration. + */ +void RDC_GetHardwareConfig(RDC_Type *base, rdc_hardware_config_t *config) +{ + assert(NULL != config); + + rdc_vir_reg_t vir; + vir._u32 = base->VIR; + + *config = vir._vir; +} + +/*! + * brief Set master domain assignment + * + * param base RDC peripheral base address. + * param master Which master to set. + * param domainAssignment Pointer to the assignment. + */ +void RDC_SetMasterDomainAssignment(RDC_Type *base, rdc_master_t master, const rdc_domain_assignment_t *domainAssignment) +{ + assert((uint32_t)master < RDC_MDA_COUNT); + + rdc_mda_reg_t mda; + + mda._mda = *domainAssignment; + + base->MDA[master] = mda._u32; +} + +/*! + * brief Get default master domain assignment + * + * The default configuration is: + * code + assignment->domainId = 0U; + assignment->lock = 0U; + endcode + * + * param domainAssignment Pointer to the assignment. + */ +void RDC_GetDefaultMasterDomainAssignment(rdc_domain_assignment_t *domainAssignment) +{ + assert(NULL != domainAssignment); + + rdc_mda_reg_t mda; + mda._u32 = 0U; + + *domainAssignment = mda._mda; +} + +/*! + * brief Set peripheral access policy. + * + * param base RDC peripheral base address. + * param config Pointer to the policy configuration. + */ +void RDC_SetPeriphAccessConfig(RDC_Type *base, const rdc_periph_access_config_t *config) +{ + assert((uint32_t)config->periph < RDC_PDAP_COUNT); + + uint32_t periph = (uint32_t)config->periph; + uint32_t regPDAP = config->policy; + + if (config->lock) + { + regPDAP |= RDC_PDAP_LCK_MASK; + } + + if (config->enableSema) + { + regPDAP |= RDC_PDAP_SREQ_MASK; + } + + base->PDAP[periph] = regPDAP; + + __DSB(); +} + +/*! + * brief Get default peripheral access policy. + * + * The default configuration is: + * code + config->lock = false; + config->enableSema = false; + config->policy = RDC_ACCESS_POLICY(0, kRDC_ReadWrite) | + RDC_ACCESS_POLICY(1, kRDC_ReadWrite) | + RDC_ACCESS_POLICY(2, kRDC_ReadWrite) | + RDC_ACCESS_POLICY(3, kRDC_ReadWrite); + endcode + * + * param config Pointer to the policy configuration. + */ +void RDC_GetDefaultPeriphAccessConfig(rdc_periph_access_config_t *config) +{ + assert(NULL != config); + + /* Initializes the configure structure to zero. */ + (void)memset(config, 0, sizeof(*config)); + + config->lock = false; + config->enableSema = false; + config->policy = RDC_ACCESS_POLICY(0U, kRDC_ReadWrite) | RDC_ACCESS_POLICY(1U, kRDC_ReadWrite) | + RDC_ACCESS_POLICY(2U, kRDC_ReadWrite) | RDC_ACCESS_POLICY(3U, kRDC_ReadWrite); +} + +/*! + * brief Set memory region access policy. + * + * Note that when setting the baseAddress and endAddress in p config, + * should be aligned to the region resolution, see rdc_mem_t + * definitions. + * + * param base RDC peripheral base address. + * param config Pointer to the policy configuration. + */ +void RDC_SetMemAccessConfig(RDC_Type *base, const rdc_mem_access_config_t *config) +{ + assert((uint32_t)config->mem < RDC_MRC_COUNT); + + uint32_t mem = (uint32_t)config->mem; + /* The configuration is enabled by default. */ + uint32_t regMRC = config->policy | RDC_MRC_ENA_MASK; + + if (config->lock) + { + regMRC |= RDC_MRC_LCK_MASK; + } + +#if (defined(FSL_FEATURE_RDC_MEM_REGION_ADDR_SHIFT) && FSL_FEATURE_RDC_MEM_REGION_ADDR_SHIFT) + base->MR[mem].MRSA = (uint32_t)(config->baseAddress >> (uint32_t)FSL_FEATURE_RDC_MEM_REGION_ADDR_SHIFT); + base->MR[mem].MREA = (uint32_t)(config->endAddress >> (uint32_t)FSL_FEATURE_RDC_MEM_REGION_ADDR_SHIFT); +#else + base->MR[mem].MRSA = (uint32_t)config->baseAddress; + base->MR[mem].MREA = (uint32_t)config->endAddress; +#endif + base->MR[mem].MRC = regMRC; + + __DSB(); +} + +/*! + * brief Get default memory region access policy. + * + * The default configuration is: + * code + config->lock = false; + config->baseAddress = 0; + config->endAddress = 0; + config->policy = RDC_ACCESS_POLICY(0, kRDC_ReadWrite) | + RDC_ACCESS_POLICY(1, kRDC_ReadWrite) | + RDC_ACCESS_POLICY(2, kRDC_ReadWrite) | + RDC_ACCESS_POLICY(3, kRDC_ReadWrite); + endcode + * + * param config Pointer to the policy configuration. + */ +void RDC_GetDefaultMemAccessConfig(rdc_mem_access_config_t *config) +{ + assert(NULL != config); + + /* Initializes the configure structure to zero. */ + (void)memset(config, 0, sizeof(*config)); + + config->lock = false; + config->baseAddress = 0; + config->endAddress = 0; + config->policy = RDC_ACCESS_POLICY(0U, kRDC_ReadWrite) | RDC_ACCESS_POLICY(1U, kRDC_ReadWrite) | + RDC_ACCESS_POLICY(2U, kRDC_ReadWrite) | RDC_ACCESS_POLICY(3U, kRDC_ReadWrite); +} + +/*! + * brief Get the memory region violation status. + * + * The first access violation is captured. Subsequent violations are ignored + * until the status register is cleared. Contents are cleared upon reading the + * register. Clearing of contents occurs only when the status is read by the + * memory region's associated domain ID(s). + * + * param base RDC peripheral base address. + * param mem Which memory region to get. + * param status The returned status. + */ +void RDC_GetMemViolationStatus(RDC_Type *base, rdc_mem_t mem, rdc_mem_status_t *status) +{ + assert((uint32_t)mem < RDC_MRC_COUNT); + + uint32_t regMRVS = base->MR[mem].MRVS; + + status->hasViolation = ((regMRVS & RDC_MRVS_AD_MASK) != 0U); + status->domainID = (uint8_t)((regMRVS & RDC_MRVS_VDID_MASK) >> RDC_MRVS_VDID_SHIFT); +#if (defined(FSL_FEATURE_RDC_MEM_REGION_ADDR_SHIFT) && FSL_FEATURE_RDC_MEM_REGION_ADDR_SHIFT) + regMRVS &= RDC_MRVS_VADR_MASK; + status->address = ((uint64_t)regMRVS) << (uint32_t)FSL_FEATURE_RDC_MEM_REGION_ADDR_SHIFT; +#else + regMRVS &= RDC_MRVS_VADR_MASK; + status->address = (uint64_t)regMRVS; +#endif +} |