/* * Copyright (c) 2016, Freescale Semiconductor, Inc. * Copyright 2016, NXP * All rights reserved. * * * SPDX-License-Identifier: BSD-3-Clause */ #include "fsl_common.h" #include "fsl_reset.h" /******************************************************************************* * Definitions ******************************************************************************/ /* Component ID definition, used by tools. */ #ifndef FSL_COMPONENT_ID #define FSL_COMPONENT_ID "platform.drivers.reset" #endif /******************************************************************************* * Variables ******************************************************************************/ /******************************************************************************* * Prototypes ******************************************************************************/ /******************************************************************************* * Code ******************************************************************************/ #if ((defined(FSL_FEATURE_SOC_SYSCON_COUNT) && (FSL_FEATURE_SOC_SYSCON_COUNT > 0)) || \ (defined(FSL_FEATURE_SOC_ASYNC_SYSCON_COUNT) && (FSL_FEATURE_SOC_ASYNC_SYSCON_COUNT > 0))) /*! * brief Assert reset to peripheral. * * Asserts reset signal to specified peripheral module. * * param peripheral Assert reset to this peripheral. The enum argument contains encoding of reset register * and reset bit position in the reset register. */ void RESET_SetPeripheralReset(reset_ip_name_t peripheral) { const uint32_t regIndex = ((uint32_t)peripheral & 0xFFFF0000u) >> 16; const uint32_t bitPos = ((uint32_t)peripheral & 0x0000FFFFu); const uint32_t bitMask = 1UL << bitPos; assert(bitPos < 32UL); /* ASYNC_SYSCON registers have offset 1024 */ if (regIndex >= SYSCON_PRESETCTRL_COUNT) { /* reset register is in ASYNC_SYSCON */ /* set bit */ ASYNC_SYSCON->ASYNCPRESETCTRLSET = bitMask; /* wait until it reads 0b1 */ while (0u == (ASYNC_SYSCON->ASYNCPRESETCTRL & bitMask)) { } } else { /* reset register is in SYSCON */ /* set bit */ SYSCON->PRESETCTRLSET[regIndex] = bitMask; /* wait until it reads 0b1 */ while (0u == (SYSCON->PRESETCTRL[regIndex] & bitMask)) { } } } /*! * brief Clear reset to peripheral. * * Clears reset signal to specified peripheral module, allows it to operate. * * param peripheral Clear reset to this peripheral. The enum argument contains encoding of reset register * and reset bit position in the reset register. */ void RESET_ClearPeripheralReset(reset_ip_name_t peripheral) { const uint32_t regIndex = ((uint32_t)peripheral & 0xFFFF0000u) >> 16; const uint32_t bitPos = ((uint32_t)peripheral & 0x0000FFFFu); const uint32_t bitMask = 1UL << bitPos; assert(bitPos < 32UL); /* ASYNC_SYSCON registers have offset 1024 */ if (regIndex >= SYSCON_PRESETCTRL_COUNT) { /* reset register is in ASYNC_SYSCON */ /* clear bit */ ASYNC_SYSCON->ASYNCPRESETCTRLCLR = bitMask; /* wait until it reads 0b0 */ while (bitMask == (ASYNC_SYSCON->ASYNCPRESETCTRL & bitMask)) { } } else { /* reset register is in SYSCON */ /* clear bit */ SYSCON->PRESETCTRLCLR[regIndex] = bitMask; /* wait until it reads 0b0 */ while (bitMask == (SYSCON->PRESETCTRL[regIndex] & bitMask)) { } } } /*! * brief Reset peripheral module. * * Reset peripheral module. * * param peripheral Peripheral to reset. The enum argument contains encoding of reset register * and reset bit position in the reset register. */ void RESET_PeripheralReset(reset_ip_name_t peripheral) { RESET_SetPeripheralReset(peripheral); RESET_ClearPeripheralReset(peripheral); } /*! * brief Set slave core to reset state and hold. */ void RESET_SetSlaveCoreReset(void) { uint32_t cpuctrl = (SYSCON->CPUCTRL & ~0x7F80U) | 0xC0C48000U; /* CM4 is the master. */ if (SYSCON_CPUCTRL_MASTERCPU_MASK == (cpuctrl & SYSCON_CPUCTRL_MASTERCPU_MASK)) { SYSCON->CPUCTRL = cpuctrl | SYSCON_CPUCTRL_CM0RSTEN_MASK; } /* CM0 is the master. */ else { SYSCON->CPUCTRL = cpuctrl | SYSCON_CPUCTRL_CM4RSTEN_MASK; } } /*! * brief Release slave core from reset state. */ void RESET_ClearSlaveCoreReset(void) { uint32_t cpuctrl = (SYSCON->CPUCTRL & ~0x7F80U) | 0xC0C48000U; /* CM4 is the master. */ if (SYSCON_CPUCTRL_MASTERCPU_MASK == (cpuctrl & SYSCON_CPUCTRL_MASTERCPU_MASK)) { SYSCON->CPUCTRL = cpuctrl & ~SYSCON_CPUCTRL_CM0RSTEN_MASK; } /* CM0 is the master. */ else { SYSCON->CPUCTRL = cpuctrl & ~SYSCON_CPUCTRL_CM4RSTEN_MASK; } } /*! * brief Reset slave core with the boot entry. */ void RESET_SlaveCoreReset(uint32_t bootAddr, uint32_t bootStackPointer) { volatile uint32_t i = 10U; SYSCON->CPSTACK = bootStackPointer; SYSCON->CPBOOT = bootAddr; RESET_SetSlaveCoreReset(); while(0U != i--){} RESET_ClearSlaveCoreReset(); } #endif /* FSL_FEATURE_SOC_SYSCON_COUNT || FSL_FEATURE_SOC_ASYNC_SYSCON_COUNT */