1 /*
2  * Copyright (c) 2015, Freescale Semiconductor, Inc.
3  * Copyright 2016-2017, 2020 NXP
4  * All rights reserved.
5  *
6  * SPDX-License-Identifier: BSD-3-Clause
7  */
8 
9 #ifndef _FSL_SMC_H_
10 #define _FSL_SMC_H_
11 
12 #include "fsl_common.h"
13 
14 /*! @addtogroup smc */
15 /*! @{ */
16 
17 /*******************************************************************************
18  * Definitions
19  ******************************************************************************/
20 
21 /*! @name Driver version */
22 /*@{*/
23 /*! @brief SMC driver version */
24 #define FSL_SMC_DRIVER_VERSION (MAKE_VERSION(2, 0, 7))
25 /*@}*/
26 
27 /*!
28  * @brief Power Modes Protection
29  */
30 typedef enum _smc_power_mode_protection
31 {
32 #if (defined(FSL_FEATURE_SMC_HAS_VERY_LOW_LEAKAGE_STOP_MODE) && FSL_FEATURE_SMC_HAS_VERY_LOW_LEAKAGE_STOP_MODE)
33     kSMC_AllowPowerModeVlls = SMC_PMPROT_AVLLS_MASK, /*!< Allow Very-low-leakage Stop Mode. */
34 #endif
35 #if (defined(FSL_FEATURE_SMC_HAS_LOW_LEAKAGE_STOP_MODE) && FSL_FEATURE_SMC_HAS_LOW_LEAKAGE_STOP_MODE)
36     kSMC_AllowPowerModeLls = SMC_PMPROT_ALLS_MASK, /*!< Allow Low-leakage Stop Mode.      */
37 #endif                                             /* FSL_FEATURE_SMC_HAS_LOW_LEAKAGE_STOP_MODE */
38     kSMC_AllowPowerModeVlp = SMC_PMPROT_AVLP_MASK, /*!< Allow Very-Low-power Mode.        */
39 #if (defined(FSL_FEATURE_SMC_HAS_HIGH_SPEED_RUN_MODE) && FSL_FEATURE_SMC_HAS_HIGH_SPEED_RUN_MODE)
40     kSMC_AllowPowerModeHsrun = SMC_PMPROT_AHSRUN_MASK, /*!< Allow High-speed Run mode.        */
41 #endif                                                 /* FSL_FEATURE_SMC_HAS_HIGH_SPEED_RUN_MODE */
42     kSMC_AllowPowerModeAll = (0U
43 #if (defined(FSL_FEATURE_SMC_HAS_VERY_LOW_LEAKAGE_STOP_MODE) && FSL_FEATURE_SMC_HAS_VERY_LOW_LEAKAGE_STOP_MODE)
44                               | SMC_PMPROT_AVLLS_MASK
45 #endif
46 #if (defined(FSL_FEATURE_SMC_HAS_LOW_LEAKAGE_STOP_MODE) && FSL_FEATURE_SMC_HAS_LOW_LEAKAGE_STOP_MODE)
47                               | SMC_PMPROT_ALLS_MASK
48 #endif /* FSL_FEATURE_SMC_HAS_LOW_LEAKAGE_STOP_MODE */
49                               | SMC_PMPROT_AVLP_MASK
50 #if (defined(FSL_FEATURE_SMC_HAS_HIGH_SPEED_RUN_MODE) && FSL_FEATURE_SMC_HAS_HIGH_SPEED_RUN_MODE)
51                               | kSMC_AllowPowerModeHsrun
52 #endif                          /* FSL_FEATURE_SMC_HAS_HIGH_SPEED_RUN_MODE */
53                               ) /*!< Allow all power mode.              */
54 } smc_power_mode_protection_t;
55 
56 /*!
57  * @brief Power Modes in PMSTAT
58  */
59 typedef enum _smc_power_state
60 {
61     kSMC_PowerStateRun  = 0x01U << 0U, /*!< 0000_0001 - Current power mode is RUN   */
62     kSMC_PowerStateStop = 0x01U << 1U, /*!< 0000_0010 - Current power mode is STOP  */
63     kSMC_PowerStateVlpr = 0x01U << 2U, /*!< 0000_0100 - Current power mode is VLPR  */
64     kSMC_PowerStateVlpw = 0x01U << 3U, /*!< 0000_1000 - Current power mode is VLPW  */
65     kSMC_PowerStateVlps = 0x01U << 4U, /*!< 0001_0000 - Current power mode is VLPS  */
66 #if (defined(FSL_FEATURE_SMC_HAS_LOW_LEAKAGE_STOP_MODE) && FSL_FEATURE_SMC_HAS_LOW_LEAKAGE_STOP_MODE)
67     kSMC_PowerStateLls = 0x01U << 5U, /*!< 0010_0000 - Current power mode is LLS   */
68 #endif                                /* FSL_FEATURE_SMC_HAS_LOW_LEAKAGE_STOP_MODE */
69 #if (defined(FSL_FEATURE_SMC_HAS_VERY_LOW_LEAKAGE_STOP_MODE) && FSL_FEATURE_SMC_HAS_VERY_LOW_LEAKAGE_STOP_MODE)
70     kSMC_PowerStateVlls = 0x01U << 6U, /*!< 0100_0000 - Current power mode is VLLS  */
71 #endif
72 #if (defined(FSL_FEATURE_SMC_HAS_HIGH_SPEED_RUN_MODE) && FSL_FEATURE_SMC_HAS_HIGH_SPEED_RUN_MODE)
73     kSMC_PowerStateHsrun = 0x01U << 7U /*!< 1000_0000 - Current power mode is HSRUN */
74 #endif                                 /* FSL_FEATURE_SMC_HAS_HIGH_SPEED_RUN_MODE */
75 } smc_power_state_t;
76 
77 /*!
78  * @brief Run mode definition
79  */
80 typedef enum _smc_run_mode
81 {
82     kSMC_RunNormal = 0U, /*!< Normal RUN mode.             */
83     kSMC_RunVlpr   = 2U, /*!< Very-low-power RUN mode.     */
84 #if (defined(FSL_FEATURE_SMC_HAS_HIGH_SPEED_RUN_MODE) && FSL_FEATURE_SMC_HAS_HIGH_SPEED_RUN_MODE)
85     kSMC_Hsrun = 3U /*!< High-speed Run mode (HSRUN). */
86 #endif              /* FSL_FEATURE_SMC_HAS_HIGH_SPEED_RUN_MODE */
87 } smc_run_mode_t;
88 
89 /*!
90  * @brief Stop mode definition
91  */
92 typedef enum _smc_stop_mode
93 {
94     kSMC_StopNormal = 0U, /*!< Normal STOP mode.           */
95     kSMC_StopVlps   = 2U, /*!< Very-low-power STOP mode.   */
96 #if (defined(FSL_FEATURE_SMC_HAS_LOW_LEAKAGE_STOP_MODE) && FSL_FEATURE_SMC_HAS_LOW_LEAKAGE_STOP_MODE)
97     kSMC_StopLls = 3U, /*!< Low-leakage Stop mode.      */
98 #endif                 /* FSL_FEATURE_SMC_HAS_LOW_LEAKAGE_STOP_MODE */
99 #if (defined(FSL_FEATURE_SMC_HAS_VERY_LOW_LEAKAGE_STOP_MODE) && FSL_FEATURE_SMC_HAS_VERY_LOW_LEAKAGE_STOP_MODE)
100     kSMC_StopVlls = 4U /*!< Very-low-leakage Stop mode. */
101 #endif
102 } smc_stop_mode_t;
103 
104 #if (defined(FSL_FEATURE_SMC_USE_VLLSCTRL_REG) && FSL_FEATURE_SMC_USE_VLLSCTRL_REG) ||     \
105     (defined(FSL_FEATURE_SMC_USE_STOPCTRL_VLLSM) && FSL_FEATURE_SMC_USE_STOPCTRL_VLLSM) || \
106     (defined(FSL_FEATURE_SMC_HAS_LLS_SUBMODE) && FSL_FEATURE_SMC_HAS_LLS_SUBMODE)
107 /*!
108  * @brief VLLS/LLS stop sub mode definition
109  */
110 typedef enum _smc_stop_submode
111 {
112     kSMC_StopSub0 = 0U, /*!< Stop submode 0, for VLLS0/LLS0. */
113     kSMC_StopSub1 = 1U, /*!< Stop submode 1, for VLLS1/LLS1. */
114     kSMC_StopSub2 = 2U, /*!< Stop submode 2, for VLLS2/LLS2. */
115     kSMC_StopSub3 = 3U  /*!< Stop submode 3, for VLLS3/LLS3. */
116 } smc_stop_submode_t;
117 #endif
118 
119 /*!
120  * @brief Partial STOP option
121  */
122 typedef enum _smc_partial_stop_mode
123 {
124     kSMC_PartialStop  = 0U, /*!< STOP - Normal Stop mode*/
125     kSMC_PartialStop1 = 1U, /*!< Partial Stop with both system and bus clocks disabled*/
126     kSMC_PartialStop2 = 2U, /*!< Partial Stop with system clock disabled and bus clock enabled*/
127 } smc_partial_stop_option_t;
128 
129 /*!
130  * @brief _smc_status, SMC configuration status.
131  */
132 enum
133 {
134     kStatus_SMC_StopAbort = MAKE_STATUS(kStatusGroup_POWER, 0) /*!< Entering Stop mode is abort*/
135 };
136 
137 #if (defined(FSL_FEATURE_SMC_HAS_VERID) && FSL_FEATURE_SMC_HAS_VERID)
138 /*!
139  * @brief IP version ID definition.
140  */
141 typedef struct _smc_version_id
142 {
143     uint16_t feature; /*!< Feature Specification Number. */
144     uint8_t minor;    /*!< Minor version number.         */
145     uint8_t major;    /*!< Major version number.         */
146 } smc_version_id_t;
147 #endif /* FSL_FEATURE_SMC_HAS_VERID */
148 
149 #if (defined(FSL_FEATURE_SMC_HAS_PARAM) && FSL_FEATURE_SMC_HAS_PARAM)
150 /*!
151  * @brief IP parameter definition.
152  */
153 typedef struct _smc_param
154 {
155     bool hsrunEnable; /*!< HSRUN mode enable. */
156     bool llsEnable;   /*!< LLS mode enable.   */
157     bool lls2Enable;  /*!< LLS2 mode enable.  */
158     bool vlls0Enable; /*!< VLLS0 mode enable. */
159 } smc_param_t;
160 #endif /* FSL_FEATURE_SMC_HAS_PARAM */
161 
162 #if (defined(FSL_FEATURE_SMC_HAS_LLS_SUBMODE) && FSL_FEATURE_SMC_HAS_LLS_SUBMODE) || \
163     (defined(FSL_FEATURE_SMC_HAS_LPOPO) && FSL_FEATURE_SMC_HAS_LPOPO)
164 /*!
165  * @brief SMC Low-Leakage Stop power mode configuration.
166  */
167 typedef struct _smc_power_mode_lls_config
168 {
169 #if (defined(FSL_FEATURE_SMC_HAS_LLS_SUBMODE) && FSL_FEATURE_SMC_HAS_LLS_SUBMODE)
170     smc_stop_submode_t subMode; /*!< Low-leakage Stop sub-mode */
171 #endif
172 #if (defined(FSL_FEATURE_SMC_HAS_LPOPO) && FSL_FEATURE_SMC_HAS_LPOPO)
173     bool enableLpoClock; /*!< Enable LPO clock in LLS mode */
174 #endif
175 } smc_power_mode_lls_config_t;
176 #endif /* (FSL_FEATURE_SMC_HAS_LLS_SUBMODE || FSL_FEATURE_SMC_HAS_LPOPO) */
177 
178 #if (defined(FSL_FEATURE_SMC_HAS_VERY_LOW_LEAKAGE_STOP_MODE) && FSL_FEATURE_SMC_HAS_VERY_LOW_LEAKAGE_STOP_MODE)
179 /*!
180  * @brief SMC Very Low-Leakage Stop power mode configuration.
181  */
182 typedef struct _smc_power_mode_vlls_config
183 {
184 #if (defined(FSL_FEATURE_SMC_USE_VLLSCTRL_REG) && FSL_FEATURE_SMC_USE_VLLSCTRL_REG) ||     \
185     (defined(FSL_FEATURE_SMC_USE_STOPCTRL_VLLSM) && FSL_FEATURE_SMC_USE_STOPCTRL_VLLSM) || \
186     (defined(FSL_FEATURE_SMC_HAS_LLS_SUBMODE) && FSL_FEATURE_SMC_HAS_LLS_SUBMODE)
187     smc_stop_submode_t subMode; /*!< Very Low-leakage Stop sub-mode */
188 #endif
189 #if (defined(FSL_FEATURE_SMC_HAS_PORPO) && FSL_FEATURE_SMC_HAS_PORPO)
190     bool enablePorDetectInVlls0; /*!< Enable Power on reset detect in VLLS mode */
191 #endif
192 #if (defined(FSL_FEATURE_SMC_HAS_RAM2_POWER_OPTION) && FSL_FEATURE_SMC_HAS_RAM2_POWER_OPTION)
193     bool enableRam2InVlls2; /*!< Enable RAM2 power in VLLS2 */
194 #endif
195 #if (defined(FSL_FEATURE_SMC_HAS_LPOPO) && FSL_FEATURE_SMC_HAS_LPOPO)
196     bool enableLpoClock; /*!< Enable LPO clock in VLLS mode */
197 #endif
198 } smc_power_mode_vlls_config_t;
199 #endif
200 
201 /*******************************************************************************
202  * API
203  ******************************************************************************/
204 
205 #if defined(__cplusplus)
206 extern "C" {
207 #endif /* __cplusplus */
208 
209 /*! @name System mode controller APIs*/
210 /*@{*/
211 
212 #if (defined(FSL_FEATURE_SMC_HAS_VERID) && FSL_FEATURE_SMC_HAS_VERID)
213 /*!
214  * @brief Gets the SMC version ID.
215  *
216  * This function gets the SMC version ID, including major version number,
217  * minor version number, and feature specification number.
218  *
219  * @param base SMC peripheral base address.
220  * @param versionId     Pointer to the version ID structure.
221  */
SMC_GetVersionId(SMC_Type * base,smc_version_id_t * versionId)222 static inline void SMC_GetVersionId(SMC_Type *base, smc_version_id_t *versionId)
223 {
224     *((uint32_t *)(uint32_t)versionId) = base->VERID;
225 }
226 #endif /* FSL_FEATURE_SMC_HAS_VERID */
227 
228 #if (defined(FSL_FEATURE_SMC_HAS_PARAM) && FSL_FEATURE_SMC_HAS_PARAM)
229 /*!
230  * @brief Gets the SMC parameter.
231  *
232  * This function gets the SMC parameter including the enabled power mdoes.
233  *
234  * @param base SMC peripheral base address.
235  * @param param         Pointer to the SMC param structure.
236  */
237 void SMC_GetParam(SMC_Type *base, smc_param_t *param);
238 #endif
239 
240 /*!
241  * @brief Configures all power mode protection settings.
242  *
243  * This function  configures the power mode protection settings for
244  * supported power modes in the specified chip family. The available power modes
245  * are defined in the smc_power_mode_protection_t. This should be done at an early
246  * system level initialization stage. See the reference manual for details.
247  * This register can only write once after the power reset.
248  *
249  * The allowed modes are passed as bit map. For example, to allow LLS and VLLS,
250  * use SMC_SetPowerModeProtection(kSMC_AllowPowerModeVlls | kSMC_AllowPowerModeVlps).
251  * To allow all modes, use SMC_SetPowerModeProtection(kSMC_AllowPowerModeAll).
252  *
253  * @param base SMC peripheral base address.
254  * @param allowedModes Bitmap of the allowed power modes.
255  */
SMC_SetPowerModeProtection(SMC_Type * base,uint8_t allowedModes)256 static inline void SMC_SetPowerModeProtection(SMC_Type *base, uint8_t allowedModes)
257 {
258     base->PMPROT = allowedModes;
259 }
260 
261 /*!
262  * @brief Gets the current power mode status.
263  *
264  * This function  returns the current power mode status. After the application
265  * switches the power mode, it should always check the status to check whether it
266  * runs into the specified mode or not. The application  should  check
267  * this mode before switching to a different mode. The system  requires that
268  * only certain modes can switch to other specific modes. See the
269  * reference manual for details and the smc_power_state_t for information about
270  * the power status.
271  *
272  * @param base SMC peripheral base address.
273  * @return Current power mode status.
274  */
SMC_GetPowerModeState(SMC_Type * base)275 static inline smc_power_state_t SMC_GetPowerModeState(SMC_Type *base)
276 {
277     return (smc_power_state_t)base->PMSTAT;
278 }
279 
280 /*!
281  * @brief Prepares to enter stop modes.
282  *
283  * This function should be called before entering STOP/VLPS/LLS/VLLS modes.
284  */
285 void SMC_PreEnterStopModes(void);
286 
287 /*!
288  * @brief Recovers after wake up from stop modes.
289  *
290  * This function should be called after wake up from STOP/VLPS/LLS/VLLS modes.
291  * It is used with @ref SMC_PreEnterStopModes.
292  */
293 void SMC_PostExitStopModes(void);
294 
295 /*!
296  * @brief Prepares to enter wait modes.
297  *
298  * This function should be called before entering WAIT/VLPW modes.
299  */
300 void SMC_PreEnterWaitModes(void);
301 
302 /*!
303  * @brief Recovers after wake up from stop modes.
304  *
305  * This function should be called after wake up from WAIT/VLPW modes.
306  * It is used with @ref SMC_PreEnterWaitModes.
307  */
308 void SMC_PostExitWaitModes(void);
309 
310 /*!
311  * @brief Configures the system to RUN power mode.
312  *
313  * @param base SMC peripheral base address.
314  * @return SMC configuration error code.
315  */
316 status_t SMC_SetPowerModeRun(SMC_Type *base);
317 
318 #if (defined(FSL_FEATURE_SMC_HAS_HIGH_SPEED_RUN_MODE) && FSL_FEATURE_SMC_HAS_HIGH_SPEED_RUN_MODE)
319 /*!
320  * @brief Configures the system to HSRUN power mode.
321  *
322  * @param base SMC peripheral base address.
323  * @return SMC configuration error code.
324  */
325 status_t SMC_SetPowerModeHsrun(SMC_Type *base);
326 #endif /* FSL_FEATURE_SMC_HAS_HIGH_SPEED_RUN_MODE */
327 
328 /*!
329  * @brief Configures the system to WAIT power mode.
330  *
331  * @param base SMC peripheral base address.
332  * @return SMC configuration error code.
333  */
334 status_t SMC_SetPowerModeWait(SMC_Type *base);
335 
336 /*!
337  * @brief Configures the system to Stop power mode.
338  *
339  * @param base SMC peripheral base address.
340  * @param  option Partial Stop mode option.
341  * @return SMC configuration error code.
342  */
343 status_t SMC_SetPowerModeStop(SMC_Type *base, smc_partial_stop_option_t option);
344 
345 #if (defined(FSL_FEATURE_SMC_HAS_LPWUI) && FSL_FEATURE_SMC_HAS_LPWUI)
346 /*!
347  * @brief Configures the system to VLPR power mode.
348  *
349  * @param base SMC peripheral base address.
350  * @param  wakeupMode Enter Normal Run mode if true, else stay in VLPR mode.
351  * @return SMC configuration error code.
352  */
353 status_t SMC_SetPowerModeVlpr(SMC_Type *base, bool wakeupMode);
354 #else
355 /*!
356  * @brief Configures the system to VLPR power mode.
357  *
358  * @param base SMC peripheral base address.
359  * @return SMC configuration error code.
360  */
361 status_t SMC_SetPowerModeVlpr(SMC_Type *base);
362 #endif /* FSL_FEATURE_SMC_HAS_LPWUI */
363 
364 /*!
365  * @brief Configures the system to VLPW power mode.
366  *
367  * @param base SMC peripheral base address.
368  * @return SMC configuration error code.
369  */
370 status_t SMC_SetPowerModeVlpw(SMC_Type *base);
371 
372 /*!
373  * @brief Configures the system to VLPS power mode.
374  *
375  * @param base SMC peripheral base address.
376  * @return SMC configuration error code.
377  */
378 status_t SMC_SetPowerModeVlps(SMC_Type *base);
379 
380 #if (defined(FSL_FEATURE_SMC_HAS_LOW_LEAKAGE_STOP_MODE) && FSL_FEATURE_SMC_HAS_LOW_LEAKAGE_STOP_MODE)
381 #if ((defined(FSL_FEATURE_SMC_HAS_LLS_SUBMODE) && FSL_FEATURE_SMC_HAS_LLS_SUBMODE) || \
382      (defined(FSL_FEATURE_SMC_HAS_LPOPO) && FSL_FEATURE_SMC_HAS_LPOPO))
383 /*!
384  * @brief Configures the system to LLS power mode.
385  *
386  * @param base SMC peripheral base address.
387  * @param  config The LLS power mode configuration structure
388  * @return SMC configuration error code.
389  */
390 status_t SMC_SetPowerModeLls(SMC_Type *base, const smc_power_mode_lls_config_t *config);
391 #else
392 /*!
393  * @brief Configures the system to LLS power mode.
394  *
395  * @param base SMC peripheral base address.
396  * @return SMC configuration error code.
397  */
398 status_t SMC_SetPowerModeLls(SMC_Type *base);
399 #endif
400 #endif /* FSL_FEATURE_SMC_HAS_LOW_LEAKAGE_STOP_MODE */
401 
402 #if (defined(FSL_FEATURE_SMC_HAS_VERY_LOW_LEAKAGE_STOP_MODE) && FSL_FEATURE_SMC_HAS_VERY_LOW_LEAKAGE_STOP_MODE)
403 /*!
404  * @brief Configures the system to VLLS power mode.
405  *
406  * @param base SMC peripheral base address.
407  * @param  config The VLLS power mode configuration structure.
408  * @return SMC configuration error code.
409  */
410 status_t SMC_SetPowerModeVlls(SMC_Type *base, const smc_power_mode_vlls_config_t *config);
411 #endif /* FSL_FEATURE_SMC_HAS_VERY_LOW_LEAKAGE_STOP_MODE */
412 
413 /*@}*/
414 
415 #if defined(__cplusplus)
416 }
417 #endif /* __cplusplus */
418 
419 /*! @}*/
420 
421 #endif /* _FSL_SMC_H_ */
422