1 /* 2 * Copyright (c) 2016, Freescale Semiconductor, Inc. 3 * Copyright 2016-2017 NXP 4 * All rights reserved. 5 * 6 * SPDX-License-Identifier: BSD-3-Clause 7 */ 8 9 #include "fsl_msmc.h" 10 11 #if defined(__riscv) 12 #define CONFIG_NORMAL_SLEEP EVENT_UNIT->SLPCTRL = (EVENT_UNIT->SLPCTRL & ~0x03) | (1 << 0) 13 #define CONFIG_DEEP_SLEEP EVENT_UNIT->SLPCTRL |= 0x03; 14 #else 15 #define CONFIG_NORMAL_SLEEP SCB->SCR &= ~SCB_SCR_SLEEPDEEP_Msk 16 #define CONFIG_DEEP_SLEEP SCB->SCR |= SCB_SCR_SLEEPDEEP_Msk 17 #endif 18 SMC_SetPowerModeRun(SMC_Type * base)19status_t SMC_SetPowerModeRun(SMC_Type *base) 20 { 21 uint32_t reg; 22 23 reg = base->PMCTRL; 24 /* configure Normal RUN mode */ 25 reg &= ~SMC_PMCTRL_RUNM_MASK; 26 reg |= (kSMC_RunNormal << SMC_PMCTRL_RUNM_SHIFT); 27 base->PMCTRL = reg; 28 29 return kStatus_Success; 30 } 31 SMC_SetPowerModeHsrun(SMC_Type * base)32status_t SMC_SetPowerModeHsrun(SMC_Type *base) 33 { 34 uint32_t reg; 35 36 reg = base->PMCTRL; 37 /* configure High Speed RUN mode */ 38 reg &= ~SMC_PMCTRL_RUNM_MASK; 39 reg |= (kSMC_Hsrun << SMC_PMCTRL_RUNM_SHIFT); 40 base->PMCTRL = reg; 41 42 return kStatus_Success; 43 } 44 SMC_SetPowerModeWait(SMC_Type * base)45status_t SMC_SetPowerModeWait(SMC_Type *base) 46 { 47 /* configure Normal Wait mode */ 48 CONFIG_NORMAL_SLEEP; 49 50 __DSB(); 51 __WFI(); 52 __ISB(); 53 54 return kStatus_Success; 55 } 56 SMC_SetPowerModeStop(SMC_Type * base,smc_partial_stop_option_t option)57status_t SMC_SetPowerModeStop(SMC_Type *base, smc_partial_stop_option_t option) 58 { 59 uint32_t reg; 60 61 /* configure the Partial Stop mode in Noraml Stop mode */ 62 reg = base->PMCTRL; 63 reg &= ~(SMC_PMCTRL_PSTOPO_MASK | SMC_PMCTRL_STOPM_MASK); 64 reg |= ((uint32_t)option << SMC_PMCTRL_PSTOPO_SHIFT) | (kSMC_StopNormal << SMC_PMCTRL_STOPM_SHIFT); 65 base->PMCTRL = reg; 66 67 /* Set the SLEEPDEEP bit to enable deep sleep mode (stop mode) */ 68 CONFIG_DEEP_SLEEP; 69 70 /* read back to make sure the configuration valid before entering stop mode */ 71 (void)base->PMCTRL; 72 __DSB(); 73 __WFI(); 74 __ISB(); 75 76 #if (defined(FSL_FEATURE_SMC_HAS_PMCTRL_STOPA) && FSL_FEATURE_SMC_HAS_PMCTRL_STOPA) 77 /* check whether the power mode enter Stop mode succeed */ 78 if (base->PMCTRL & SMC_PMCTRL_STOPA_MASK) 79 { 80 return kStatus_SMC_StopAbort; 81 } 82 else 83 { 84 return kStatus_Success; 85 } 86 #else 87 return kStatus_Success; 88 #endif /* FSL_FEATURE_SMC_HAS_PMCTRL_STOPA */ 89 } 90 SMC_SetPowerModeVlpr(SMC_Type * base)91status_t SMC_SetPowerModeVlpr(SMC_Type *base) 92 { 93 uint32_t reg; 94 95 reg = base->PMCTRL; 96 /* configure VLPR mode */ 97 reg &= ~SMC_PMCTRL_RUNM_MASK; 98 reg |= (kSMC_RunVlpr << SMC_PMCTRL_RUNM_SHIFT); 99 base->PMCTRL = reg; 100 101 return kStatus_Success; 102 } 103 SMC_SetPowerModeVlpw(SMC_Type * base)104status_t SMC_SetPowerModeVlpw(SMC_Type *base) 105 { 106 /* configure VLPW mode */ 107 /* Clear the SLEEPDEEP bit to disable deep sleep mode */ 108 CONFIG_NORMAL_SLEEP; 109 110 __DSB(); 111 __WFI(); 112 __ISB(); 113 114 return kStatus_Success; 115 } 116 SMC_SetPowerModeVlps(SMC_Type * base)117status_t SMC_SetPowerModeVlps(SMC_Type *base) 118 { 119 uint32_t reg; 120 121 /* configure VLPS mode */ 122 reg = base->PMCTRL; 123 reg &= ~SMC_PMCTRL_STOPM_MASK; 124 reg |= (kSMC_StopVlps << SMC_PMCTRL_STOPM_SHIFT); 125 base->PMCTRL = reg; 126 127 /* Set the SLEEPDEEP bit to enable deep sleep mode */ 128 CONFIG_DEEP_SLEEP; 129 130 /* read back to make sure the configuration valid before enter stop mode */ 131 (void)base->PMCTRL; 132 __DSB(); 133 __WFI(); 134 __ISB(); 135 136 #if (defined(FSL_FEATURE_SMC_HAS_PMCTRL_STOPA) && FSL_FEATURE_SMC_HAS_PMCTRL_STOPA) 137 /* check whether the power mode enter Stop mode succeed */ 138 if (base->PMCTRL & SMC_PMCTRL_STOPA_MASK) 139 { 140 return kStatus_SMC_StopAbort; 141 } 142 else 143 { 144 return kStatus_Success; 145 } 146 #else 147 return kStatus_Success; 148 #endif /* FSL_FEATURE_SMC_HAS_PMCTRL_STOPA */ 149 } 150 SMC_SetPowerModeLls(SMC_Type * base)151status_t SMC_SetPowerModeLls(SMC_Type *base) 152 { 153 uint32_t reg; 154 155 /* configure to LLS mode */ 156 reg = base->PMCTRL; 157 reg &= ~SMC_PMCTRL_STOPM_MASK; 158 reg |= (kSMC_StopLls << SMC_PMCTRL_STOPM_SHIFT); 159 base->PMCTRL = reg; 160 161 /* Set the SLEEPDEEP bit to enable deep sleep mode */ 162 CONFIG_DEEP_SLEEP; 163 164 /* read back to make sure the configuration valid before entering stop mode */ 165 (void)base->PMCTRL; 166 __DSB(); 167 __WFI(); 168 __ISB(); 169 170 #if (defined(FSL_FEATURE_SMC_HAS_PMCTRL_STOPA) && FSL_FEATURE_SMC_HAS_PMCTRL_STOPA) 171 /* check whether the power mode enter Stop mode succeed */ 172 if (base->PMCTRL & SMC_PMCTRL_STOPA_MASK) 173 { 174 return kStatus_SMC_StopAbort; 175 } 176 else 177 { 178 return kStatus_Success; 179 } 180 #else 181 return kStatus_Success; 182 #endif /* FSL_FEATURE_SMC_HAS_PMCTRL_STOPA */ 183 } 184 185 #if (defined(FSL_FEATURE_SMC_HAS_SUB_STOP_MODE) && FSL_FEATURE_SMC_HAS_SUB_STOP_MODE) 186 187 #if (defined(FSL_FEATURE_SMC_HAS_STOP_SUBMODE0) && FSL_FEATURE_SMC_HAS_STOP_SUBMODE0) SMC_SetPowerModeVlls0(SMC_Type * base)188status_t SMC_SetPowerModeVlls0(SMC_Type *base) 189 { 190 uint32_t reg; 191 192 /* configure to VLLS mode */ 193 reg = base->PMCTRL; 194 reg &= ~SMC_PMCTRL_STOPM_MASK; 195 reg |= (kSMC_StopVlls0 << SMC_PMCTRL_STOPM_SHIFT); 196 base->PMCTRL = reg; 197 198 /* Set the SLEEPDEEP bit to enable deep sleep mode */ 199 CONFIG_DEEP_SLEEP; 200 201 /* read back to make sure the configuration valid before enter stop mode */ 202 (void)base->PMCTRL; 203 __DSB(); 204 __WFI(); 205 __ISB(); 206 207 return kStatus_Success; 208 } 209 #endif /* FSL_FEATURE_SMC_HAS_STOP_SUBMODE0 */ 210 211 #if (defined(FSL_FEATURE_SMC_HAS_STOP_SUBMODE2) && FSL_FEATURE_SMC_HAS_STOP_SUBMODE2) SMC_SetPowerModeVlls2(SMC_Type * base)212status_t SMC_SetPowerModeVlls2(SMC_Type *base) 213 { 214 uint32_t reg; 215 216 /* configure to VLLS mode */ 217 reg = base->PMCTRL; 218 reg &= ~SMC_PMCTRL_STOPM_MASK; 219 reg |= (kSMC_StopVlls2 << SMC_PMCTRL_STOPM_SHIFT); 220 base->PMCTRL = reg; 221 222 /* Set the SLEEPDEEP bit to enable deep sleep mode */ 223 CONFIG_DEEP_SLEEP; 224 225 /* read back to make sure the configuration valid before enter stop mode */ 226 (void)base->PMCTRL; 227 __DSB(); 228 __WFI(); 229 __ISB(); 230 231 return kStatus_Success; 232 } 233 #endif /* FSL_FEATURE_SMC_HAS_STOP_SUBMODE0 */ 234 235 #else /* FSL_FEATURE_SMC_HAS_SUB_STOP_MODE */ SMC_SetPowerModeVlls(SMC_Type * base)236status_t SMC_SetPowerModeVlls(SMC_Type *base) 237 { 238 uint32_t reg; 239 240 /* configure to VLLS mode */ 241 reg = base->PMCTRL; 242 reg &= ~SMC_PMCTRL_STOPM_MASK; 243 reg |= (kSMC_StopVlls << SMC_PMCTRL_STOPM_SHIFT); 244 base->PMCTRL = reg; 245 246 #if defined(__riscv) 247 EVENT->SCR = (EVENT->SCR & ~0x03) | (1 << 1); 248 #else 249 /* Set the SLEEPDEEP bit to enable deep sleep mode */ 250 CONFIG_DEEP_SLEEP; 251 #endif 252 253 /* read back to make sure the configuration valid before enter stop mode */ 254 (void)base->PMCTRL; 255 __DSB(); 256 __WFI(); 257 __ISB(); 258 259 #if (defined(FSL_FEATURE_SMC_HAS_PMCTRL_STOPA) && FSL_FEATURE_SMC_HAS_PMCTRL_STOPA) 260 /* check whether the power mode enter Stop mode succeed */ 261 if (base->PMCTRL & SMC_PMCTRL_STOPA_MASK) 262 { 263 return kStatus_SMC_StopAbort; 264 } 265 else 266 { 267 return kStatus_Success; 268 } 269 #else 270 return kStatus_Success; 271 #endif /* FSL_FEATURE_SMC_HAS_PMCTRL_STOPA */ 272 } 273 #endif /* FSL_FEATURE_SMC_HAS_SUB_STOP_MODE */ 274 SMC_ConfigureResetPinFilter(SMC_Type * base,const smc_reset_pin_filter_config_t * config)275void SMC_ConfigureResetPinFilter(SMC_Type *base, const smc_reset_pin_filter_config_t *config) 276 { 277 assert(config); 278 279 uint32_t reg; 280 281 reg = SMC_RPC_FILTCFG(config->slowClockFilterCount) | SMC_RPC_FILTEN(config->enableFilter); 282 #if (defined(FSL_FEATURE_SMC_HAS_RPC_LPOFEN) && FSL_FEATURE_SMC_HAS_RPC_LPOFEN) 283 if (config->enableLpoFilter) 284 { 285 reg |= SMC_RPC_LPOFEN_MASK; 286 } 287 #endif /* FSL_FEATURE_SMC_HAS_RPC_LPOFEN */ 288 289 base->RPC = reg; 290 } 291