diff options
Diffstat (limited to '')
-rw-r--r-- | bsps/arm/imxrt/mcux-sdk/drivers/rdc/fsl_rdc.c | 310 | ||||
-rw-r--r-- | bsps/arm/imxrt/mcux-sdk/drivers/rdc/fsl_rdc.h | 447 | ||||
-rw-r--r-- | bsps/arm/imxrt/mcux-sdk/drivers/rdc_sema42/fsl_rdc_sema42.c | 236 | ||||
-rw-r--r-- | bsps/arm/imxrt/mcux-sdk/drivers/rdc_sema42/fsl_rdc_sema42.h | 194 |
4 files changed, 1187 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 +} diff --git a/bsps/arm/imxrt/mcux-sdk/drivers/rdc/fsl_rdc.h b/bsps/arm/imxrt/mcux-sdk/drivers/rdc/fsl_rdc.h new file mode 100644 index 0000000000..41d3f5aca1 --- /dev/null +++ b/bsps/arm/imxrt/mcux-sdk/drivers/rdc/fsl_rdc.h @@ -0,0 +1,447 @@ +/* + * Copyright 2017-2021 NXP + * All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#ifndef _FSL_RDC_H_ +#define _FSL_RDC_H_ + +#include "fsl_common.h" + +/*! + * @addtogroup rdc + * @{ + */ + +/****************************************************************************** + * Definitions + *****************************************************************************/ +#define FSL_RDC_DRIVER_VERSION (MAKE_VERSION(2, 2, 0)) + +#define RDC_ACCESS_POLICY(domainID, policy) (uint16_t)((uint16_t)(policy) << ((domainID)*2U)) + +/*! + * @brief RDC hardware configuration. + */ +typedef struct _rdc_hardware_config +{ + uint32_t domainNumber : 4; /*!< Number of domains. */ + uint32_t masterNumber : 8; /*!< Number of bus masters. */ + uint32_t periphNumber : 8; /*!< Number of peripherals. */ + uint32_t memNumber : 8; /*!< Number of memory regions. */ + uint32_t : 4; +} rdc_hardware_config_t; + +/*! + * @brief RDC interrupts + */ +enum _rdc_interrupts +{ + kRDC_RestoreCompleteInterrupt = RDC_INTCTRL_RCI_EN_MASK, + /*!< Interrupt generated when the RDC has completed restoring state to a recently re-powered memory regions. */ +}; + +/*! + * @brief RDC status + */ +enum _rdc_flags +{ + kRDC_PowerDownDomainOn = RDC_STAT_PDS_MASK, /*!< Power down domain is ON. */ +}; + +/*! + * @brief Master domain assignment. + */ +typedef struct _rdc_domain_assignment +{ + uint32_t domainId : 2U; /*!< Domain ID. */ + uint32_t : 29U; /*!< Reserved. */ + uint32_t lock : 1U; /*!< Lock the domain assignment. */ +} rdc_domain_assignment_t; + +/*! + * @brief Access permission policy. + */ +enum _rdc_access_policy +{ + kRDC_NoAccess = 0, /*!< Could not read or write. */ + kRDC_WriteOnly = 1, /*!< Write only. */ + kRDC_ReadOnly = 2, /*!< Read only. */ + kRDC_ReadWrite = 3, /*!< Read and write. */ +}; + +/*! + * @brief Peripheral domain access permission configuration. + */ +typedef struct _rdc_periph_access_config +{ + rdc_periph_t periph; /*!< Peripheral name. */ + bool lock; /*!< Lock the permission until reset. */ + bool enableSema; /*!< Enable semaphore or not, when enabled, master should + call @ref RDC_SEMA42_Lock to lock the semaphore gate + accordingly before access the peripheral. */ + uint16_t policy; /*!< Access policy. */ +} rdc_periph_access_config_t; + +/*! + * @brief Memory region domain access control configuration. + * + * Note that when setting the @ref baseAddress and @ref endAddress, + * should be aligned to the region resolution, see rdc_mem_t + * definitions. + */ +typedef struct _rdc_mem_access_config +{ + rdc_mem_t mem; /*!< Memory region descriptor name. */ + + bool lock; /*!< Lock the configuration. */ + uint64_t baseAddress; /*!< Start address of the memory region. */ + uint64_t endAddress; /*!< End address of the memory region. */ + uint16_t policy; /*!< Access policy. */ +} rdc_mem_access_config_t; + +/*! + * @brief Memory region access violation status. + */ +typedef struct _rdc_mem_status +{ + bool hasViolation; /*!< Violating happens or not. */ + uint8_t domainID; /*!< Violating Domain ID. */ + uint64_t address; /*!< Violating Address. */ +} rdc_mem_status_t; + +/******************************************************************************* + * API + ******************************************************************************/ + +#if defined(__cplusplus) +extern "C" { +#endif + +/*! + * @brief Initializes the RDC module. + * + * This function enables the RDC clock. + * + * @param base RDC peripheral base address. + */ +void RDC_Init(RDC_Type *base); + +/*! + * @brief De-initializes the RDC module. + * + * This function disables the RDC clock. + * + * @param base RDC peripheral base address. + */ +void RDC_Deinit(RDC_Type *base); + +/*! + * @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); + +/*! + * @brief Enable interrupts. + * + * @param base RDC peripheral base address. + * @param mask Interrupts to enable, it is OR'ed value of enum @ref _rdc_interrupts. + */ +static inline void RDC_EnableInterrupts(RDC_Type *base, uint32_t mask) +{ + base->INTCTRL |= mask; +} + +/*! + * @brief Disable interrupts. + * + * @param base RDC peripheral base address. + * @param mask Interrupts to disable, it is OR'ed value of enum @ref _rdc_interrupts. + */ +static inline void RDC_DisableInterrupts(RDC_Type *base, uint32_t mask) +{ + base->INTCTRL &= ~mask; +} + +/*! + * @brief Get the interrupt pending status. + * + * @param base RDC peripheral base address. + * @return Interrupts pending status, it is OR'ed value of enum @ref _rdc_interrupts. + */ +static inline uint32_t RDC_GetInterruptStatus(RDC_Type *base) +{ + return base->INTSTAT; +} + +/*! + * @brief Clear interrupt pending status. + * + * @param base RDC peripheral base address. + * @param mask Status to clear, it is OR'ed value of enum @ref _rdc_interrupts. + */ +static inline void RDC_ClearInterruptStatus(RDC_Type *base, uint32_t mask) +{ + base->INTSTAT = mask; +} + +/*! + * @brief Get RDC status. + * + * @param base RDC peripheral base address. + * @return mask RDC status, it is OR'ed value of enum @ref _rdc_flags. + */ +static inline uint32_t RDC_GetStatus(RDC_Type *base) +{ + return base->STAT; +} + +/*! + * @brief Clear RDC status. + * + * @param base RDC peripheral base address. + * @param mask RDC status to clear, it is OR'ed value of enum @ref _rdc_flags. + */ +static inline void RDC_ClearStatus(RDC_Type *base, uint32_t mask) +{ + base->STAT = mask; +} + +/*! + * @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); + +/*! + * @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); + +/*! + * @brief Lock master domain assignment + * + * Once locked, it could not be unlocked until next reset. + * + * @param base RDC peripheral base address. + * @param master Which master to lock. + */ +static inline void RDC_LockMasterDomainAssignment(RDC_Type *base, rdc_master_t master) +{ + assert((uint32_t)master < RDC_MDA_COUNT); + + base->MDA[master] |= RDC_MDA_LCK_MASK; + __DSB(); +} + +/*! + * @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); + +/*! + * @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); + +/*! + * @brief Lock peripheral access policy configuration. + * + * Once locked, it could not be unlocked until reset. + * + * @param base RDC peripheral base address. + * @param periph Which peripheral to lock. + */ +static inline void RDC_LockPeriphAccessConfig(RDC_Type *base, rdc_periph_t periph) +{ + assert((uint32_t)periph < RDC_PDAP_COUNT); + + base->PDAP[periph] |= RDC_PDAP_LCK_MASK; + __DSB(); +} + +/*! + * @brief Get the peripheral access policy for specific domain. + * + * @param base RDC peripheral base address. + * @param periph Which peripheral to get. + * @param domainId Get policy for which domain. + * @return Access policy, see @ref _rdc_access_policy. + */ +static inline uint8_t RDC_GetPeriphAccessPolicy(RDC_Type *base, rdc_periph_t periph, uint8_t domainId) +{ + assert((uint32_t)periph < RDC_PDAP_COUNT); + + return (uint8_t)((base->PDAP[periph] >> (domainId * 2U)) & 0x03U); +} + +/*! + * @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); + +/*! + * @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); + +/*! + * @brief Lock memory access policy configuration. + * + * Once locked, it could not be unlocked until reset. After locked, you can + * only call @ref RDC_SetMemAccessValid to enable the configuration, but can not + * disable it or change other settings. + * + * @param base RDC peripheral base address. + * @param mem Which memory region to lock. + */ +static inline void RDC_LockMemAccessConfig(RDC_Type *base, rdc_mem_t mem) +{ + assert((uint32_t)mem < RDC_MRC_COUNT); + + base->MR[mem].MRC |= RDC_MRC_LCK_MASK; + __DSB(); +} + +/*! + * @brief Enable or disable memory access policy configuration. + * + * @param base RDC peripheral base address. + * @param mem Which memory region to operate. + * @param valid Pass in true to valid, false to invalid. + */ +static inline void RDC_SetMemAccessValid(RDC_Type *base, rdc_mem_t mem, bool valid) +{ + assert((uint32_t)mem < RDC_MRC_COUNT); + + if (valid) + { + base->MR[mem].MRC |= RDC_MRC_ENA_MASK; + } + else + { + base->MR[mem].MRC &= ~RDC_MRC_ENA_MASK; + } + __DSB(); +} + +/*! + * @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); + +/*! + * @brief Clear the memory region violation flag. + * + * @param base RDC peripheral base address. + * @param mem Which memory region to clear. + */ +static inline void RDC_ClearMemViolationFlag(RDC_Type *base, rdc_mem_t mem) +{ + assert((uint32_t)mem < RDC_MRC_COUNT); + + base->MR[mem].MRVS = RDC_MRVS_AD_MASK; +} + +/*! + * @brief Get the memory region access policy for specific domain. + * + * @param base RDC peripheral base address. + * @param mem Which memory region to get. + * @param domainId Get policy for which domain. + * @return Access policy, see @ref _rdc_access_policy. + */ +static inline uint8_t RDC_GetMemAccessPolicy(RDC_Type *base, rdc_mem_t mem, uint8_t domainId) +{ + assert((uint32_t)mem < RDC_MRC_COUNT); + + return (uint8_t)((base->MR[mem].MRC >> (domainId * 2U)) & 0x03U); +} + +/*! + * @brief Gets the domain ID of the current bus master. + * + * This function returns the domain ID of the current bus master. + * + * @param base RDC peripheral base address. + * @return Domain ID of current bus master. + */ +static inline uint8_t RDC_GetCurrentMasterDomainId(RDC_Type *base) +{ + return (uint8_t)((base->STAT & RDC_STAT_DID_MASK) >> RDC_STAT_DID_SHIFT); +} + +#if defined(__cplusplus) +} +#endif + +/*! + * @} + */ + +#endif /* _FSL_RDC_H_ */ diff --git a/bsps/arm/imxrt/mcux-sdk/drivers/rdc_sema42/fsl_rdc_sema42.c b/bsps/arm/imxrt/mcux-sdk/drivers/rdc_sema42/fsl_rdc_sema42.c new file mode 100644 index 0000000000..00189e49a8 --- /dev/null +++ b/bsps/arm/imxrt/mcux-sdk/drivers/rdc_sema42/fsl_rdc_sema42.c @@ -0,0 +1,236 @@ +/* + * Copyright 2017-2020, 2022 NXP + * All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#include "fsl_rdc_sema42.h" + +/****************************************************************************** + * Definitions + *****************************************************************************/ + +/* Component ID definition, used by tools. */ +#ifndef FSL_COMPONENT_ID +#define FSL_COMPONENT_ID "platform.drivers.rdc_sema42" +#endif + +/* The first number write to RSTGDP when reset RDC_SEMA42 gate. */ +#define RDC_SEMA42_GATE_RESET_PATTERN_1 (0xE2U) +/* The second number write to RSTGDP when reset RDC_SEMA42 gate. */ +#define RDC_SEMA42_GATE_RESET_PATTERN_2 (0x1DU) + +#if !defined(RDC_SEMAPHORE_GATE_COUNT) +/* Compatible remap. */ +#define RDC_SEMAPHORE_GATE_LDOM(x) RDC_SEMAPHORE_GATE0_LDOM(x) +#define RDC_SEMAPHORE_GATE_GTFSM(x) RDC_SEMAPHORE_GATE0_GTFSM(x) +#define RDC_SEMAPHORE_GATE_LDOM_MASK RDC_SEMAPHORE_GATE0_LDOM_MASK +#define RDC_SEMAPHORE_GATE_LDOM_SHIFT RDC_SEMAPHORE_GATE0_LDOM_SHIFT +#endif + +/******************************************************************************* + * Prototypes + ******************************************************************************/ + +/*! + * @brief Get instance number for RDC_SEMA42 module. + * + * @param base RDC_SEMA42 peripheral base address. + */ +uint32_t RDC_SEMA42_GetInstance(RDC_SEMAPHORE_Type *base); + +/******************************************************************************* + * Variables + ******************************************************************************/ + +/*! @brief Pointers to sema42 bases for each instance. */ +static RDC_SEMAPHORE_Type *const s_sema42Bases[] = RDC_SEMAPHORE_BASE_PTRS; + +#if !(defined(FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) && FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) +#if defined(RDC_SEMA42_CLOCKS) +/*! @brief Pointers to sema42 clocks for each instance. */ +static const clock_ip_name_t s_sema42Clocks[] = RDC_SEMA42_CLOCKS; +#endif +#endif /* FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL */ + +/****************************************************************************** + * CODE + *****************************************************************************/ + +uint32_t RDC_SEMA42_GetInstance(RDC_SEMAPHORE_Type *base) +{ + uint32_t instance; + + /* Find the instance index from base address mappings. */ + for (instance = 0; instance < ARRAY_SIZE(s_sema42Bases); instance++) + { + if (s_sema42Bases[instance] == base) + { + break; + } + } + + assert(instance < ARRAY_SIZE(s_sema42Bases)); + + return instance; +} + +/*! + * brief Initializes the RDC_SEMA42 module. + * + * This function initializes the RDC_SEMA42 module. It only enables the clock but does + * not reset the gates because the module might be used by other processors + * at the same time. To reset the gates, call either RDC_SEMA42_ResetGate or + * RDC_SEMA42_ResetAllGates function. + * + * param base RDC_SEMA42 peripheral base address. + */ +void RDC_SEMA42_Init(RDC_SEMAPHORE_Type *base) +{ +#if !(defined(FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) && FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) +#if defined(RDC_SEMA42_CLOCKS) + CLOCK_EnableClock(s_sema42Clocks[RDC_SEMA42_GetInstance(base)]); +#endif +#endif /* FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL */ +} + +/*! + * brief De-initializes the RDC_SEMA42 module. + * + * This function de-initializes the RDC_SEMA42 module. It only disables the clock. + * + * param base RDC_SEMA42 peripheral base address. + */ +void RDC_SEMA42_Deinit(RDC_SEMAPHORE_Type *base) +{ +#if !(defined(FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) && FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) +#if defined(RDC_SEMA42_CLOCKS) + CLOCK_DisableClock(s_sema42Clocks[RDC_SEMA42_GetInstance(base)]); +#endif +#endif /* FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL */ +} + +/*! + * brief Tries to lock the RDC_SEMA42 gate. + * + * This function tries to lock the specific RDC_SEMA42 gate. If the gate has been + * locked by another processor, this function returns an error code. + * + * param base RDC_SEMA42 peripheral base address. + * param gateNum Gate number to lock. + * param masterIndex Current processor master index. + * param domainId Current processor domain ID. + * + * retval kStatus_Success Lock the sema42 gate successfully. + * retval kStatus_Failed Sema42 gate has been locked by another processor. + */ +status_t RDC_SEMA42_TryLock(RDC_SEMAPHORE_Type *base, uint8_t gateNum, uint8_t masterIndex, uint8_t domainId) +{ + assert(gateNum < RDC_SEMA42_GATE_COUNT); + + status_t status = kStatus_Success; + uint8_t regGate; + + ++masterIndex; + + regGate = (uint8_t)(RDC_SEMAPHORE_GATE_LDOM(domainId) | RDC_SEMAPHORE_GATE_GTFSM(masterIndex)); + + /* Try to lock. */ + RDC_SEMA42_GATEn(base, gateNum) = masterIndex; + + /* Check locked or not. */ + if (regGate != RDC_SEMA42_GATEn(base, gateNum)) + { + status = kStatus_Fail; + } + + return status; +} + +/*! + * brief Locks the RDC_SEMA42 gate. + * + * This function locks the specific RDC_SEMA42 gate. If the gate has been + * locked by other processors, this function waits until it is unlocked and then + * lock it. + * + * param base RDC_SEMA42 peripheral base address. + * param gateNum Gate number to lock. + * param masterIndex Current processor master index. + * param domainId Current processor domain ID. + */ +void RDC_SEMA42_Lock(RDC_SEMAPHORE_Type *base, uint8_t gateNum, uint8_t masterIndex, uint8_t domainId) +{ + while (kStatus_Success != RDC_SEMA42_TryLock(base, gateNum, masterIndex, domainId)) + { + } +} + +/*! + * brief Gets which domain has currently locked the gate. + * + * param base RDC_SEMA42 peripheral base address. + * param gateNum Gate number. + * + * return Return -1 if the gate is not locked by any domain, otherwise return the + * domain ID. + */ +int32_t RDC_SEMA42_GetLockDomainID(RDC_SEMAPHORE_Type *base, uint8_t gateNum) +{ + assert(gateNum < RDC_SEMA42_GATE_COUNT); + + int32_t ret; + uint8_t regGate = RDC_SEMA42_GATEn(base, gateNum); + + /* Current gate is not locked. */ + if (0U == (regGate & RDC_SEMAPHORE_GATE_GTFSM_MASK)) + { + ret = -1; + } + else + { + ret = (int32_t)((uint8_t)((regGate & RDC_SEMAPHORE_GATE_LDOM_MASK) >> RDC_SEMAPHORE_GATE_LDOM_SHIFT)); + } + + return ret; +} + +/*! + * brief Resets the RDC_SEMA42 gate to an unlocked status. + * + * This function resets a RDC_SEMA42 gate to an unlocked status. + * + * param base RDC_SEMA42 peripheral base address. + * param gateNum Gate number. + * + * retval kStatus_Success RDC_SEMA42 gate is reset successfully. + * retval kStatus_Failed Some other reset process is ongoing. + */ +status_t RDC_SEMA42_ResetGate(RDC_SEMAPHORE_Type *base, uint8_t gateNum) +{ + status_t status; + + /* + * Reset all gates if gateNum >= RDC_SEMA42_GATE_NUM_RESET_ALL + * Reset specific gate if gateNum < RDC_SEMA42_GATE_COUNT + */ + + /* Check whether some reset is ongoing. */ + if (0U != (base->RSTGT_R & RDC_SEMAPHORE_RSTGT_R_RSTGSM_MASK)) + { + status = kStatus_Fail; + } + else + { + /* First step. */ + base->RSTGT_W = RDC_SEMAPHORE_RSTGT_W_RSTGDP(RDC_SEMA42_GATE_RESET_PATTERN_1); + /* Second step. */ + base->RSTGT_W = + RDC_SEMAPHORE_RSTGT_W_RSTGDP(RDC_SEMA42_GATE_RESET_PATTERN_2) | RDC_SEMAPHORE_RSTGT_W_RSTGTN(gateNum); + + status = kStatus_Success; + } + + return status; +} diff --git a/bsps/arm/imxrt/mcux-sdk/drivers/rdc_sema42/fsl_rdc_sema42.h b/bsps/arm/imxrt/mcux-sdk/drivers/rdc_sema42/fsl_rdc_sema42.h new file mode 100644 index 0000000000..ddd9e4bbc2 --- /dev/null +++ b/bsps/arm/imxrt/mcux-sdk/drivers/rdc_sema42/fsl_rdc_sema42.h @@ -0,0 +1,194 @@ +/* + * Copyright 2017-2020, 2022 NXP + * All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#ifndef _FSL_RDC_SEMA42_H_ +#define _FSL_RDC_SEMA42_H_ + +#include "fsl_common.h" + +/*! + * @addtogroup rdc_sema42 + * @{ + */ + +/****************************************************************************** + * Definitions + *****************************************************************************/ + +/*! @name Driver version */ +/*@{*/ +/*! @brief RDC_SEMA42 driver version */ +#define FSL_RDC_SEMA42_DRIVER_VERSION (MAKE_VERSION(2, 0, 4)) +/*@}*/ + +/*! @brief The number to reset all RDC_SEMA42 gates. */ +#define RDC_SEMA42_GATE_NUM_RESET_ALL (64U) + +#if defined(RDC_SEMAPHORE_GATE_COUNT) + +/*! @brief RDC_SEMA42 gate n register address. */ +#define RDC_SEMA42_GATEn(base, n) ((base)->GATE[(n)]) + +/*! @brief RDC_SEMA42 gate count. */ +#define RDC_SEMA42_GATE_COUNT (RDC_SEMAPHORE_GATE_COUNT) + +#else /* RDC_SEMAPHORE_GATE_COUNT */ + +/*! @brief RDC_SEMA42 gate n register address. */ +#define RDC_SEMA42_GATEn(base, n) (((volatile uint8_t *)(&((base)->GATE0)))[(n)]) + +/*! @brief RDC_SEMA42 gate count. */ +#define RDC_SEMA42_GATE_COUNT (64U) + +/* Compatible remap. */ +#define RDC_SEMAPHORE_GATE_GTFSM_MASK RDC_SEMAPHORE_GATE0_GTFSM_MASK + +#endif /* RDC_SEMAPHORE_GATE_COUNT */ + +/******************************************************************************* + * API + ******************************************************************************/ + +#if defined(__cplusplus) +extern "C" { +#endif + +/*! + * @brief Initializes the RDC_SEMA42 module. + * + * This function initializes the RDC_SEMA42 module. It only enables the clock but does + * not reset the gates because the module might be used by other processors + * at the same time. To reset the gates, call either RDC_SEMA42_ResetGate or + * RDC_SEMA42_ResetAllGates function. + * + * @param base RDC_SEMA42 peripheral base address. + */ +void RDC_SEMA42_Init(RDC_SEMAPHORE_Type *base); + +/*! + * @brief De-initializes the RDC_SEMA42 module. + * + * This function de-initializes the RDC_SEMA42 module. It only disables the clock. + * + * @param base RDC_SEMA42 peripheral base address. + */ +void RDC_SEMA42_Deinit(RDC_SEMAPHORE_Type *base); + +/*! + * @brief Tries to lock the RDC_SEMA42 gate. + * + * This function tries to lock the specific RDC_SEMA42 gate. If the gate has been + * locked by another processor, this function returns an error code. + * + * @param base RDC_SEMA42 peripheral base address. + * @param gateNum Gate number to lock. + * @param masterIndex Current processor master index. + * @param domainId Current processor domain ID. + * + * @retval kStatus_Success Lock the sema42 gate successfully. + * @retval kStatus_Failed Sema42 gate has been locked by another processor. + */ +status_t RDC_SEMA42_TryLock(RDC_SEMAPHORE_Type *base, uint8_t gateNum, uint8_t masterIndex, uint8_t domainId); + +/*! + * @brief Locks the RDC_SEMA42 gate. + * + * This function locks the specific RDC_SEMA42 gate. If the gate has been + * locked by other processors, this function waits until it is unlocked and then + * lock it. + * + * @param base RDC_SEMA42 peripheral base address. + * @param gateNum Gate number to lock. + * @param masterIndex Current processor master index. + * @param domainId Current processor domain ID. + */ +void RDC_SEMA42_Lock(RDC_SEMAPHORE_Type *base, uint8_t gateNum, uint8_t masterIndex, uint8_t domainId); + +/*! + * @brief Unlocks the RDC_SEMA42 gate. + * + * This function unlocks the specific RDC_SEMA42 gate. It only writes unlock value + * to the RDC_SEMA42 gate register. However, it does not check whether the RDC_SEMA42 gate is locked + * by the current processor or not. As a result, if the RDC_SEMA42 gate is not locked by the current + * processor, this function has no effect. + * + * @param base RDC_SEMA42 peripheral base address. + * @param gateNum Gate number to unlock. + */ +static inline void RDC_SEMA42_Unlock(RDC_SEMAPHORE_Type *base, uint8_t gateNum) +{ + assert(gateNum < RDC_SEMA42_GATE_COUNT); + + RDC_SEMA42_GATEn(base, gateNum) = 0U; +} + +/*! + * @brief Gets which master has currently locked the gate. + * + * @param base RDC_SEMA42 peripheral base address. + * @param gateNum Gate number. + * + * @return Return -1 if the gate is not locked by any master, otherwise return the + * master index. + */ +static inline int32_t RDC_SEMA42_GetLockMasterIndex(RDC_SEMAPHORE_Type *base, uint8_t gateNum) +{ + assert(gateNum < RDC_SEMA42_GATE_COUNT); + + uint8_t regGate = RDC_SEMA42_GATEn(base, gateNum); + + return (int32_t)((uint8_t)(regGate & RDC_SEMAPHORE_GATE_GTFSM_MASK)) - 1; +} + +/*! + * @brief Gets which domain has currently locked the gate. + * + * @param base RDC_SEMA42 peripheral base address. + * @param gateNum Gate number. + * + * @return Return -1 if the gate is not locked by any domain, otherwise return the + * domain ID. + */ +int32_t RDC_SEMA42_GetLockDomainID(RDC_SEMAPHORE_Type *base, uint8_t gateNum); + +/*! + * @brief Resets the RDC_SEMA42 gate to an unlocked status. + * + * This function resets a RDC_SEMA42 gate to an unlocked status. + * + * @param base RDC_SEMA42 peripheral base address. + * @param gateNum Gate number. + * + * @retval kStatus_Success RDC_SEMA42 gate is reset successfully. + * @retval kStatus_Failed Some other reset process is ongoing. + */ +status_t RDC_SEMA42_ResetGate(RDC_SEMAPHORE_Type *base, uint8_t gateNum); + +/*! + * @brief Resets all RDC_SEMA42 gates to an unlocked status. + * + * This function resets all RDC_SEMA42 gate to an unlocked status. + * + * @param base RDC_SEMA42 peripheral base address. + * + * @retval kStatus_Success RDC_SEMA42 is reset successfully. + * @retval kStatus_RDC_SEMA42_Reseting Some other reset process is ongoing. + */ +static inline status_t RDC_SEMA42_ResetAllGates(RDC_SEMAPHORE_Type *base) +{ + return RDC_SEMA42_ResetGate(base, RDC_SEMA42_GATE_NUM_RESET_ALL); +} + +#if defined(__cplusplus) +} +#endif + +/*! + * @} + */ + +#endif /* _FSL_RDC_SEMA42_H_ */ |