2 * Copyright (c) 2013 - 2014, Freescale Semiconductor, Inc.
5 * Redistribution and use in source and binary forms, with or without modification,
6 * are permitted provided that the following conditions are met:
8 * o Redistributions of source code must retain the above copyright notice, this list
9 * of conditions and the following disclaimer.
11 * o Redistributions in binary form must reproduce the above copyright notice, this
12 * list of conditions and the following disclaimer in the documentation and/or
13 * other materials provided with the distribution.
15 * o Neither the name of Freescale Semiconductor, Inc. nor the names of its
16 * contributors may be used to endorse or promote products derived from this
17 * software without specific prior written permission.
19 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
20 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
21 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
22 * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR
23 * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
24 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
25 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
26 * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
27 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
28 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
31 #include "fsl_smc_hal.h"
33 /*******************************************************************************
35 ******************************************************************************/
37 /*******************************************************************************
39 ******************************************************************************/
40 /*FUNCTION**********************************************************************
42 * Function Name : SMC_HAL_SetMode
43 * Description : Config the power mode
44 * This function will configure the power mode control for any run, stop and
45 * stop submode if needed. It will also configure the power options for specific
46 * power mode. Application should follow the proper procedure to configure and
47 * switch power mode between the different run and stop mode. Refer to reference
48 * manual for the proper procedure and supported power mode that can be configured
49 * and switch between each other. Refert to smc_power_mode_config_t for required
50 * parameters to configure the power mode and the supported options. Other options
51 * may need to configure through the hal driver individaully. Refer to hal driver
54 *END**************************************************************************/
55 smc_hal_error_code_t
SMC_HAL_SetMode(uint32_t baseAddr
, const smc_power_mode_config_t
*powerModeConfig
)
57 smc_hal_error_code_t retCode
= kSmcHalSuccess
;
59 volatile unsigned int dummyread
;
60 smc_stop_mode_t stopMode
;
61 smc_run_mode_t runMode
;
62 power_mode_stat_t modeStat
;
63 power_modes_t powerModeName
= powerModeConfig
->powerModeName
;
65 /* verify the power mode name*/
66 assert(powerModeName
< kPowerModeMax
);
68 #if FSL_FEATURE_SMC_HAS_LPWUI
69 /* check lpwui option*/
70 if (powerModeConfig
->lpwuiOption
)
72 /* check current stat*/
73 currentStat
= SMC_HAL_GetStat(baseAddr
);
75 /* if not in VLPR stat, could not set to RUN*/
76 if (currentStat
== kStatRun
)
78 SMC_HAL_SetLpwuiMode(baseAddr
, powerModeConfig
->lpwuiOptionValue
);
83 /* branch based on power mode name*/
84 switch (powerModeName
)
88 if (powerModeName
== kPowerModeRun
)
90 /* mode setting for normal RUN*/
96 /* mode setting for VLPR*/
101 /* check current stat*/
102 currentStat
= SMC_HAL_GetStat(baseAddr
);
104 /* if not in VLPR stat, could not set to RUN*/
105 if (currentStat
!= modeStat
)
107 retCode
= kSmcHalFailed
;
111 /* set power mode to normal RUN or VLPR*/
112 SMC_HAL_SetRunMode(baseAddr
, runMode
);
116 #if FSL_FEATURE_SMC_HAS_HIGH_SPEED_RUN_MODE
117 case kPowerModeHsrun
:
118 /* mode setting for HSRUN (high speed run) */
122 /* check current stat*/
123 currentStat
= SMC_HAL_GetStat(baseAddr
);
125 if (currentStat
!= modeStat
)
127 /* if not in the mode, return error*/
128 retCode
= kSmcHalFailed
;
132 /* set power mode to normal RUN or VLPR mode first*/
133 SMC_HAL_SetRunMode(baseAddr
, runMode
);
141 if (powerModeName
== kPowerModeWait
)
143 /* mode setting for normal RUN*/
149 /* mode setting for VLPR*/
151 modeStat
= kStatVlpr
;
154 /* check current stat*/
155 currentStat
= SMC_HAL_GetStat(baseAddr
);
157 if (currentStat
!= modeStat
)
159 /* if not in the mode, return error*/
160 retCode
= kSmcHalFailed
;
164 /* set power mode to normal RUN or VLPR mode first*/
165 SMC_HAL_SetRunMode(baseAddr
, runMode
);
168 if (retCode
== kSmcHalSuccess
)
170 /* Clear the SLEEPDEEP bit to disable deep sleep mode - enter wait mode*/
171 SCB
->SCR
&= ~SCB_SCR_SLEEPDEEP_Msk
;
179 if (powerModeName
== kPowerModeStop
)
181 #if FSL_FEATURE_SMC_HAS_HIGH_SPEED_RUN_MODE
182 /* check current stat*/
183 currentStat
= SMC_HAL_GetStat(baseAddr
);
185 if ((currentStat
== kStatHsrun
) || (SMC_HAL_GetRunMode(baseAddr
) == kSmcHsrun
))
187 retCode
= kSmcHalFailed
;
192 #if FSL_FEATURE_SMC_HAS_PSTOPO
193 if (powerModeConfig
->pstopOption
)
195 SMC_HAL_SetPstopMode(baseAddr
, powerModeConfig
->pstopOptionValue
);
199 else if (powerModeName
== kPowerModeVlps
)
208 /* set power mode to specified STOP mode*/
209 SMC_HAL_SetStopMode(baseAddr
, stopMode
);
211 #if FSL_FEATURE_SMC_HAS_LLS_SUBMODE
212 if (powerModeName
== kPowerModeLls
)
214 /* further set the stop sub mode configuration*/
215 SMC_HAL_SetStopSubMode(baseAddr
, powerModeConfig
->stopSubMode
);
219 /* wait for write to complete to SMC before stopping core */
220 dummyread
= SMC_HAL_GetStat(baseAddr
);
221 dummyread
= dummyread
+ 1;
223 /* Set the SLEEPDEEP bit to enable deep sleep mode (STOP)*/
224 SCB
->SCR
|= SCB_SCR_SLEEPDEEP_Msk
;
230 /* set power mode to specified STOP mode*/
231 SMC_HAL_SetStopMode(baseAddr
, kSmcVlls
);
233 /* further set the stop sub mode configuration*/
234 SMC_HAL_SetStopSubMode(baseAddr
, powerModeConfig
->stopSubMode
);
236 /* check if Vlls0 option needs configuration*/
237 if (powerModeConfig
->stopSubMode
== kSmcStopSub0
)
239 #if FSL_FEATURE_SMC_HAS_PORPO
240 if (powerModeConfig
->porOption
)
242 SMC_HAL_SetPorMode(baseAddr
, powerModeConfig
->porOptionValue
);
247 /* wait for write to complete to SMC before stopping core */
248 dummyread
= SMC_HAL_GetStat(baseAddr
);
249 dummyread
= dummyread
+ 1;
251 /* Set the SLEEPDEEP bit to enable deep sleep mode (STOP)*/
252 SCB
->SCR
|= SCB_SCR_SLEEPDEEP_Msk
;
257 retCode
= kSmcHalNoSuchModeName
;
264 /*FUNCTION**********************************************************************
266 * Function Name : SMC_HAL_SetProtection
267 * Description : Config all power mode protection settings
268 * This function will configure the power mode protection settings for
269 * supported power mode on the specified chip family. The availabe power modes
270 * are defined in smc_power_mode_protection_config_t. Application should provide
271 * the protect settings for all supported power mode on the chip and aslo this
272 * should be done at early system level init stage. Refer to reference manual
273 * for details. This register can only write once after power reset. So either
274 * use this function or use the individual set function if you only have single
277 *END**************************************************************************/
278 void SMC_HAL_SetProtection(uint32_t baseAddr
, smc_power_mode_protection_config_t
*protectConfig
)
280 /* initialize the setting */
281 uint8_t regValue
= 0;
283 /* check configurations for each mode and combine the seting together */
284 if (protectConfig
->vlpProt
)
286 regValue
|= BF_SMC_PMPROT_AVLP(1);
289 if (protectConfig
->llsProt
)
291 regValue
|= BF_SMC_PMPROT_ALLS(1);
294 if (protectConfig
->vllsProt
)
296 regValue
|= BF_SMC_PMPROT_AVLLS(1);
299 #if FSL_FEATURE_SMC_HAS_HIGH_SPEED_RUN_MODE
300 if (protectConfig
->hsrunProt
)
302 regValue
|= BF_SMC_PMPROT_AHSRUN(1);
306 /* write once into pmprot register*/
307 HW_SMC_PMPROT_SET(baseAddr
, regValue
);
310 /*FUNCTION**********************************************************************
312 * Function Name : SMC_HAL_SetProtectionMode
313 * Description : Config the individual power mode protection setting
314 * This function will only configure the power mode protection settings for
315 * a specified power mode on the specified chip family. The availabe power modes
316 * are defined in smc_power_mode_protection_config_t. Refer to reference manual
317 * for details. This register can only write once after power reset.
319 *END**************************************************************************/
320 void SMC_HAL_SetProtectionMode(uint32_t baseAddr
, power_modes_protect_t protect
, bool allow
)
322 /* check the setting range */
323 assert(protect
< kAllowMax
);
325 /* branch according to mode and write the setting */
331 BW_SMC_PMPROT_AVLP(baseAddr
, 1);
335 BW_SMC_PMPROT_AVLP(baseAddr
, 0);
341 BW_SMC_PMPROT_ALLS(baseAddr
, 1);
345 BW_SMC_PMPROT_ALLS(baseAddr
, 0);
351 BW_SMC_PMPROT_AVLLS(baseAddr
, 1);
355 BW_SMC_PMPROT_AVLLS(baseAddr
, 0);
358 #if FSL_FEATURE_SMC_HAS_HIGH_SPEED_RUN_MODE
362 BW_SMC_PMPROT_AHSRUN(baseAddr
, 1);
366 BW_SMC_PMPROT_AHSRUN(baseAddr
, 0);
375 /*FUNCTION**********************************************************************
377 * Function Name : SMC_HAL_GetProtectionMode
378 * Description : Get the current power mode protection setting
379 * This function will get the current power mode protection settings for
380 * a specified power mode.
382 *END**************************************************************************/
383 bool SMC_HAL_GetProtectionMode(uint32_t baseAddr
, power_modes_protect_t protect
)
385 bool retValue
= false;
387 /* check the mode range */
388 assert(protect
< kAllowMax
);
390 /* branch according to the mode and read the setting */
394 retValue
= BR_SMC_PMPROT_AVLP(baseAddr
);
397 retValue
= BR_SMC_PMPROT_ALLS(baseAddr
);
400 retValue
= BR_SMC_PMPROT_AVLLS(baseAddr
);
402 #if FSL_FEATURE_SMC_HAS_HIGH_SPEED_RUN_MODE
404 retValue
= BR_SMC_PMPROT_AHSRUN(baseAddr
);
413 /*FUNCTION**********************************************************************
415 * Function Name : SMC_HAL_SetRunMode
416 * Description : Config the RUN mode control setting
417 * This function will set the run mode settings. For example, normal run mode,
418 * very lower power run mode, etc. Refer to smc_run_mode_t for supported run
419 * mode on the chip family. Refer to reference manual for details about the
422 *END**************************************************************************/
423 void SMC_HAL_SetRunMode(uint32_t baseAddr
, smc_run_mode_t runMode
)
425 BW_SMC_PMCTRL_RUNM(baseAddr
, runMode
);
428 /*FUNCTION**********************************************************************
430 * Function Name : SMC_HAL_GetRunMode
431 * Description : Get the current RUN mode config
432 * This function will get the run mode settings. Refer to smc_run_mode_t
433 * for supported run mode on the chip family. Refer to reference manual for
434 * details about the run mode.
436 *END**************************************************************************/
437 smc_run_mode_t
SMC_HAL_GetRunMode(uint32_t baseAddr
)
439 return (smc_run_mode_t
)BR_SMC_PMCTRL_RUNM(baseAddr
);
442 /*FUNCTION**********************************************************************
444 * Function Name : SMC_HAL_SetStopMode
445 * Description : Config the STOP mode control setting
446 * This function will set the stop mode settings. For example, normal stop mode,
447 * very lower power stop mode, etc. Refer to smc_stop_mode_t for supported stop
448 * mode on the chip family. Refer to reference manual for details about the
451 *END**************************************************************************/
452 void SMC_HAL_SetStopMode(uint32_t baseAddr
, smc_stop_mode_t stopMode
)
454 BW_SMC_PMCTRL_STOPM(baseAddr
, stopMode
);
457 /*FUNCTION**********************************************************************
459 * Function Name : SMC_HAL_GetStopMode
460 * Description : Get the current STOP mode control setting
461 * This function will get the stop mode settings. For example, normal stop mode,
462 * very lower power stop mode, etc. Refer to smc_stop_mode_t for supported stop
463 * mode on the chip family. Refer to reference manual for details about the
466 *END**************************************************************************/
467 smc_stop_mode_t
SMC_HAL_GetStopMode(uint32_t baseAddr
)
469 return (smc_stop_mode_t
)BR_SMC_PMCTRL_STOPM(baseAddr
);
472 /*FUNCTION**********************************************************************
474 * Function Name : SMC_HAL_SetStopSubMode
475 * Description : Config the stop sub mode control setting
476 * This function will set the stop submode settings. Some of the stop mode will
477 * further have submode supported. Refer to smc_stop_submode_t for supported
478 * stop submode and Refer to reference manual for details about the submode
479 * for specific stop mode.
481 *END**************************************************************************/
482 void SMC_HAL_SetStopSubMode(uint32_t baseAddr
, smc_stop_submode_t stopSubMode
)
484 #if FSL_FEATURE_SMC_USE_VLLSCTRL_REG
485 BW_SMC_VLLSCTRL_VLLSM(baseAddr
, stopSubMode
);
487 #if FSL_FEATURE_SMC_USE_STOPCTRL_VLLSM
488 BW_SMC_STOPCTRL_VLLSM(baseAddr
, stopSubMode
);
490 BW_SMC_STOPCTRL_LLSM(baseAddr
, stopSubMode
);
495 /*FUNCTION**********************************************************************
497 * Function Name : SMC_HAL_GetStopSubMode
498 * Description : Get the current stop submode config
499 * This function will get the stop submode settings. Some of the stop mode will
500 * further have submode supported. Refer to smc_stop_submode_t for supported
501 * stop submode and Refer to reference manual for details about the submode
502 * for specific stop mode.
504 *END**************************************************************************/
505 smc_stop_submode_t
SMC_HAL_GetStopSubMode(uint32_t baseAddr
)
507 #if FSL_FEATURE_SMC_USE_VLLSCTRL_REG
508 return (smc_stop_submode_t
)BR_SMC_VLLSCTRL_VLLSM(baseAddr
);
510 #if FSL_FEATURE_SMC_USE_STOPCTRL_VLLSM
511 return (smc_stop_submode_t
)BR_SMC_STOPCTRL_VLLSM(baseAddr
);
513 return (smc_stop_submode_t
)BR_SMC_STOPCTRL_LLSM(baseAddr
);
518 #if FSL_FEATURE_SMC_HAS_PORPO
519 /*FUNCTION**********************************************************************
521 * Function Name : SMC_HAL_SetPorMode
522 * Description : Config the POR (power-on-reset) option
523 * This function will set the POR power option setting. It controls whether the
524 * POR detect circuit (for brown-out detection) is enabled in certain stop mode.
525 * The setting will be either enable or disable the above feature when POR
526 * happened. Refer to reference manual for details.
528 *END**************************************************************************/
529 void SMC_HAL_SetPorMode(uint32_t baseAddr
, smc_por_option_t option
)
531 #if FSL_FEATURE_SMC_USE_VLLSCTRL_REG
532 BW_SMC_VLLSCTRL_PORPO(baseAddr
, option
);
534 BW_SMC_STOPCTRL_PORPO(baseAddr
, option
);
538 /*FUNCTION**********************************************************************
540 * Function Name : SMC_HAL_GetPorMode
541 * Description : Get the config of POR option
542 * This function will set the POR power option setting. See config function
543 * header for details.
545 *END**************************************************************************/
546 smc_por_option_t
SMC_HAL_GetPorMode(uint32_t baseAddr
)
548 #if FSL_FEATURE_SMC_USE_VLLSCTRL_REG
549 return (smc_por_option_t
)BR_SMC_VLLSCTRL_PORPO(baseAddr
);
551 return (smc_por_option_t
)BR_SMC_STOPCTRL_PORPO(baseAddr
);
556 #if FSL_FEATURE_SMC_HAS_PSTOPO
557 /*FUNCTION**********************************************************************
559 * Function Name : SMC_HAL_GetPorMode
560 * Description : Config the PSTOPO (Partial Stop Option)
561 * This function will set the PSTOPO option. It controls whether a Partial
562 * Stop mode is entered when STOPM=STOP. When entering a Partial Stop mode from
563 * RUN mode, the PMC, MCG and flash remain fully powered, allowing the device
564 * to wakeup almost instantaneously at the expense of higher power consumption.
565 * In PSTOP2, only system clocks are gated allowing peripherals running on bus
566 * clock to remain fully functional. In PSTOP1, both system and bus clocks are
567 * gated. Refer to smc_pstop_option_t for supported options. Refer to reference
568 * manual for details.
570 *END**************************************************************************/
571 void SMC_HAL_SetPstopMode(uint32_t baseAddr
, smc_pstop_option_t option
)
573 BW_SMC_STOPCTRL_PSTOPO(baseAddr
, option
);
576 /*FUNCTION**********************************************************************
578 * Function Name : SMC_HAL_GetPorMode
579 * Description : Get the config of PSTOPO option
580 * This function will get the current PSTOPO option setting. Refer to config
581 * function for more details.
583 *END**************************************************************************/
584 smc_pstop_option_t
SMC_HAL_GetPstopMode(uint32_t baseAddr
)
586 return (smc_pstop_option_t
)BR_SMC_STOPCTRL_PSTOPO(baseAddr
);
590 #if FSL_FEATURE_SMC_HAS_LPOPO
591 /*FUNCTION**********************************************************************
593 * Function Name : SMC_HAL_GetPorMode
594 * Description : Config the LPO option setting
595 * This function will set the LPO option setting. It controls whether the 1kHZ
596 * LPO clock is enabled in certain lower power stop modes. Refer to
597 * smc_lpo_option_t for supported options and refer to reference manual for
598 * details about this option.
600 *END**************************************************************************/
601 void SMC_HAL_SetLpoMode(uint32_t baseAddr
, smc_lpo_option_t option
)
603 BW_SMC_STOPCTRL_LPOPO(baseAddr
, option
);
606 /*FUNCTION**********************************************************************
608 * Function Name : SMC_HAL_GetPorMode
609 * Description : Get the config of LPO option
610 * This function will get the current LPO option setting. Refer to config
611 * function for details.
613 *END**************************************************************************/
614 smc_por_option_t
SMC_HAL_GetLpoMode(uint32_t baseAddr
)
616 return (smc_por_option_t
)BR_SMC_STOPCTRL_LPOPO(baseAddr
);
620 #if FSL_FEATURE_SMC_HAS_LPWUI
621 /*FUNCTION**********************************************************************
623 * Function Name : SMC_HAL_SetLpwuiMode
624 * Description : Config the LPWUI (Low Power Wake Up on interrup) option
625 * This function will set the LPWUI option. It will cause the system to exit
626 * to normal RUN mode when any active interrupt occurs while in a certain lower
627 * power mode. Refer to smc_lpwui_option_t for supported options and refer to
628 * reference manual for more details about this option.
630 *END**************************************************************************/
631 void SMC_HAL_SetLpwuiMode(uint32_t baseAddr
, smc_lpwui_option_t option
)
633 BW_SMC_PMCTRL_LPWUI(baseAddr
, option
);
636 /*FUNCTION**********************************************************************
638 * Function Name : SMC_HAL_SetLpwuiMode
639 * Description : Get the current LPWUI option
640 * This function will get the LPWUI option. Refer to config function for more
643 *END**************************************************************************/
644 smc_lpwui_option_t
SMC_HAL_GetLpwuiMode(uint32_t baseAddr
)
646 return (smc_lpwui_option_t
)BR_SMC_PMCTRL_LPWUI(baseAddr
);
650 /*FUNCTION**********************************************************************
652 * Function Name : SMC_HAL_GetStat
653 * Description : Get the current power mode stat
654 * This function will return the current power mode stat. Once application is
655 * switching the power mode, it should always check the stat to make sure it
656 * runs into the specified mode or not. Also application will need to check
657 * this mode before switching to certain mode. The system will require that
658 * only certain mode could switch to other specific mode. Refer to the
659 * reference manual for details. Refer to _power_mode_stat for the meaning
662 *END**************************************************************************/
663 uint8_t SMC_HAL_GetStat(uint32_t baseAddr
)
665 return BR_SMC_PMSTAT_PMSTAT(baseAddr
);
668 /*******************************************************************************
670 ******************************************************************************/