--- /dev/null
+/*
+ * Copyright (c) 2016, Freescale Semiconductor, Inc.
+ * Copyright 2016-2017 NXP
+ * All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include "fsl_msmc.h"
+
+#if defined(__riscv)
+#define CONFIG_NORMAL_SLEEP EVENT_UNIT->SLPCTRL = (EVENT_UNIT->SLPCTRL & ~0x03) | (1 << 0)
+#define CONFIG_DEEP_SLEEP EVENT_UNIT->SLPCTRL |= 0x03;
+#else
+#define CONFIG_NORMAL_SLEEP SCB->SCR &= ~SCB_SCR_SLEEPDEEP_Msk
+#define CONFIG_DEEP_SLEEP SCB->SCR |= SCB_SCR_SLEEPDEEP_Msk
+#endif
+
+status_t SMC_SetPowerModeRun(SMC_Type *base)
+{
+ uint32_t reg;
+
+ reg = base->PMCTRL;
+ /* configure Normal RUN mode */
+ reg &= ~SMC_PMCTRL_RUNM_MASK;
+ reg |= (kSMC_RunNormal << SMC_PMCTRL_RUNM_SHIFT);
+ base->PMCTRL = reg;
+
+ return kStatus_Success;
+}
+
+status_t SMC_SetPowerModeHsrun(SMC_Type *base)
+{
+ uint32_t reg;
+
+ reg = base->PMCTRL;
+ /* configure High Speed RUN mode */
+ reg &= ~SMC_PMCTRL_RUNM_MASK;
+ reg |= (kSMC_Hsrun << SMC_PMCTRL_RUNM_SHIFT);
+ base->PMCTRL = reg;
+
+ return kStatus_Success;
+}
+
+status_t SMC_SetPowerModeWait(SMC_Type *base)
+{
+ /* configure Normal Wait mode */
+ CONFIG_NORMAL_SLEEP;
+
+ __DSB();
+ __WFI();
+ __ISB();
+
+ return kStatus_Success;
+}
+
+status_t SMC_SetPowerModeStop(SMC_Type *base, smc_partial_stop_option_t option)
+{
+ uint32_t reg;
+
+ /* configure the Partial Stop mode in Noraml Stop mode */
+ reg = base->PMCTRL;
+ reg &= ~(SMC_PMCTRL_PSTOPO_MASK | SMC_PMCTRL_STOPM_MASK);
+ reg |= ((uint32_t)option << SMC_PMCTRL_PSTOPO_SHIFT) | (kSMC_StopNormal << SMC_PMCTRL_STOPM_SHIFT);
+ base->PMCTRL = reg;
+
+ /* Set the SLEEPDEEP bit to enable deep sleep mode (stop mode) */
+ CONFIG_DEEP_SLEEP;
+
+ /* read back to make sure the configuration valid before entering stop mode */
+ (void)base->PMCTRL;
+ __DSB();
+ __WFI();
+ __ISB();
+
+#if (defined(FSL_FEATURE_SMC_HAS_PMCTRL_STOPA) && FSL_FEATURE_SMC_HAS_PMCTRL_STOPA)
+ /* check whether the power mode enter Stop mode succeed */
+ if (base->PMCTRL & SMC_PMCTRL_STOPA_MASK)
+ {
+ return kStatus_SMC_StopAbort;
+ }
+ else
+ {
+ return kStatus_Success;
+ }
+#else
+ return kStatus_Success;
+#endif /* FSL_FEATURE_SMC_HAS_PMCTRL_STOPA */
+}
+
+status_t SMC_SetPowerModeVlpr(SMC_Type *base)
+{
+ uint32_t reg;
+
+ reg = base->PMCTRL;
+ /* configure VLPR mode */
+ reg &= ~SMC_PMCTRL_RUNM_MASK;
+ reg |= (kSMC_RunVlpr << SMC_PMCTRL_RUNM_SHIFT);
+ base->PMCTRL = reg;
+
+ return kStatus_Success;
+}
+
+status_t SMC_SetPowerModeVlpw(SMC_Type *base)
+{
+ /* configure VLPW mode */
+ /* Clear the SLEEPDEEP bit to disable deep sleep mode */
+ CONFIG_NORMAL_SLEEP;
+
+ __DSB();
+ __WFI();
+ __ISB();
+
+ return kStatus_Success;
+}
+
+status_t SMC_SetPowerModeVlps(SMC_Type *base)
+{
+ uint32_t reg;
+
+ /* configure VLPS mode */
+ reg = base->PMCTRL;
+ reg &= ~SMC_PMCTRL_STOPM_MASK;
+ reg |= (kSMC_StopVlps << SMC_PMCTRL_STOPM_SHIFT);
+ base->PMCTRL = reg;
+
+ /* Set the SLEEPDEEP bit to enable deep sleep mode */
+ CONFIG_DEEP_SLEEP;
+
+ /* read back to make sure the configuration valid before enter stop mode */
+ (void)base->PMCTRL;
+ __DSB();
+ __WFI();
+ __ISB();
+
+#if (defined(FSL_FEATURE_SMC_HAS_PMCTRL_STOPA) && FSL_FEATURE_SMC_HAS_PMCTRL_STOPA)
+ /* check whether the power mode enter Stop mode succeed */
+ if (base->PMCTRL & SMC_PMCTRL_STOPA_MASK)
+ {
+ return kStatus_SMC_StopAbort;
+ }
+ else
+ {
+ return kStatus_Success;
+ }
+#else
+ return kStatus_Success;
+#endif /* FSL_FEATURE_SMC_HAS_PMCTRL_STOPA */
+}
+
+status_t SMC_SetPowerModeLls(SMC_Type *base)
+{
+ uint32_t reg;
+
+ /* configure to LLS mode */
+ reg = base->PMCTRL;
+ reg &= ~SMC_PMCTRL_STOPM_MASK;
+ reg |= (kSMC_StopLls << SMC_PMCTRL_STOPM_SHIFT);
+ base->PMCTRL = reg;
+
+ /* Set the SLEEPDEEP bit to enable deep sleep mode */
+ CONFIG_DEEP_SLEEP;
+
+ /* read back to make sure the configuration valid before entering stop mode */
+ (void)base->PMCTRL;
+ __DSB();
+ __WFI();
+ __ISB();
+
+#if (defined(FSL_FEATURE_SMC_HAS_PMCTRL_STOPA) && FSL_FEATURE_SMC_HAS_PMCTRL_STOPA)
+ /* check whether the power mode enter Stop mode succeed */
+ if (base->PMCTRL & SMC_PMCTRL_STOPA_MASK)
+ {
+ return kStatus_SMC_StopAbort;
+ }
+ else
+ {
+ return kStatus_Success;
+ }
+#else
+ return kStatus_Success;
+#endif /* FSL_FEATURE_SMC_HAS_PMCTRL_STOPA */
+}
+
+#if (defined(FSL_FEATURE_SMC_HAS_SUB_STOP_MODE) && FSL_FEATURE_SMC_HAS_SUB_STOP_MODE)
+
+#if (defined(FSL_FEATURE_SMC_HAS_STOP_SUBMODE0) && FSL_FEATURE_SMC_HAS_STOP_SUBMODE0)
+status_t SMC_SetPowerModeVlls0(SMC_Type *base)
+{
+ uint32_t reg;
+
+ /* configure to VLLS mode */
+ reg = base->PMCTRL;
+ reg &= ~SMC_PMCTRL_STOPM_MASK;
+ reg |= (kSMC_StopVlls0 << SMC_PMCTRL_STOPM_SHIFT);
+ base->PMCTRL = reg;
+
+ /* Set the SLEEPDEEP bit to enable deep sleep mode */
+ CONFIG_DEEP_SLEEP;
+
+ /* read back to make sure the configuration valid before enter stop mode */
+ (void)base->PMCTRL;
+ __DSB();
+ __WFI();
+ __ISB();
+
+ return kStatus_Success;
+}
+#endif /* FSL_FEATURE_SMC_HAS_STOP_SUBMODE0 */
+
+#if (defined(FSL_FEATURE_SMC_HAS_STOP_SUBMODE2) && FSL_FEATURE_SMC_HAS_STOP_SUBMODE2)
+status_t SMC_SetPowerModeVlls2(SMC_Type *base)
+{
+ uint32_t reg;
+
+ /* configure to VLLS mode */
+ reg = base->PMCTRL;
+ reg &= ~SMC_PMCTRL_STOPM_MASK;
+ reg |= (kSMC_StopVlls2 << SMC_PMCTRL_STOPM_SHIFT);
+ base->PMCTRL = reg;
+
+ /* Set the SLEEPDEEP bit to enable deep sleep mode */
+ CONFIG_DEEP_SLEEP;
+
+ /* read back to make sure the configuration valid before enter stop mode */
+ (void)base->PMCTRL;
+ __DSB();
+ __WFI();
+ __ISB();
+
+ return kStatus_Success;
+}
+#endif /* FSL_FEATURE_SMC_HAS_STOP_SUBMODE0 */
+
+#else /* FSL_FEATURE_SMC_HAS_SUB_STOP_MODE */
+status_t SMC_SetPowerModeVlls(SMC_Type *base)
+{
+ uint32_t reg;
+
+ /* configure to VLLS mode */
+ reg = base->PMCTRL;
+ reg &= ~SMC_PMCTRL_STOPM_MASK;
+ reg |= (kSMC_StopVlls << SMC_PMCTRL_STOPM_SHIFT);
+ base->PMCTRL = reg;
+
+#if defined(__riscv)
+ EVENT->SCR = (EVENT->SCR & ~0x03) | (1 << 1);
+#else
+ /* Set the SLEEPDEEP bit to enable deep sleep mode */
+ CONFIG_DEEP_SLEEP;
+#endif
+
+ /* read back to make sure the configuration valid before enter stop mode */
+ (void)base->PMCTRL;
+ __DSB();
+ __WFI();
+ __ISB();
+
+#if (defined(FSL_FEATURE_SMC_HAS_PMCTRL_STOPA) && FSL_FEATURE_SMC_HAS_PMCTRL_STOPA)
+ /* check whether the power mode enter Stop mode succeed */
+ if (base->PMCTRL & SMC_PMCTRL_STOPA_MASK)
+ {
+ return kStatus_SMC_StopAbort;
+ }
+ else
+ {
+ return kStatus_Success;
+ }
+#else
+ return kStatus_Success;
+#endif /* FSL_FEATURE_SMC_HAS_PMCTRL_STOPA */
+}
+#endif /* FSL_FEATURE_SMC_HAS_SUB_STOP_MODE */
+
+void SMC_ConfigureResetPinFilter(SMC_Type *base, const smc_reset_pin_filter_config_t *config)
+{
+ assert(config);
+
+ uint32_t reg;
+
+ reg = SMC_RPC_FILTCFG(config->slowClockFilterCount) | SMC_RPC_FILTEN(config->enableFilter);
+#if (defined(FSL_FEATURE_SMC_HAS_RPC_LPOFEN) && FSL_FEATURE_SMC_HAS_RPC_LPOFEN)
+ if (config->enableLpoFilter)
+ {
+ reg |= SMC_RPC_LPOFEN_MASK;
+ }
+#endif /* FSL_FEATURE_SMC_HAS_RPC_LPOFEN */
+
+ base->RPC = reg;
+}