/* * Copyright 2017-2020 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) { assert(gateNum < RDC_SEMA42_GATE_COUNT); uint8_t regGate; ++masterIndex; regGate = (uint8_t)(RDC_SEMAPHORE_GATE_LDOM(domainId) | RDC_SEMAPHORE_GATE_GTFSM(masterIndex)); while (regGate != RDC_SEMA42_GATEn(base, gateNum)) { /* Wait for unlocked status. */ while (0U != (RDC_SEMA42_GATEn(base, gateNum) & RDC_SEMAPHORE_GATE_GTFSM_MASK)) { } /* Lock the gate. */ RDC_SEMA42_GATEn(base, gateNum) = masterIndex; } } /*! * 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; }