1 /*
2  * Copyright 2022 NXP
3  * All rights reserved.
4  *
5  * SPDX-License-Identifier: BSD-3-Clause
6  */
7 
8 #include "fsl_soc_src.h"
9 
10 /* Component ID definition, used by tools. */
11 #ifndef FSL_COMPONENT_ID
12 #define FSL_COMPONENT_ID "platform.drivers.soc_src"
13 #endif
14 
15 /*******************************************************************************
16  * Definitions
17  ******************************************************************************/
18 #define SRC_GLOBAL_SYSTEM_RESET_BEHAVIOR_MASK (0x1U)
19 #define SRC_GLOBAL_SYSTEM_RESET_BEHAVIOR_CONFIG(resetSource, resetMode) \
20     ((uint32_t)(resetMode) << (uint32_t)(resetSource))
21 
22 /*******************************************************************************
23  * Prototypes
24  ******************************************************************************/
25 
26 /*******************************************************************************
27  * Variables
28  ******************************************************************************/
29 
30 /*******************************************************************************
31  * Code
32  ******************************************************************************/
33 
34 /*!
35  * brief Release related core reset operation.
36  *
37  * The core reset will be held until boot core to release it.
38  *
39  * param base SRC peripheral base address.
40  * param coreName The name of the reset core to be released.
41  */
SRC_ReleaseCM7(SRC_GENERAL_Type * base)42 void SRC_ReleaseCM7(SRC_GENERAL_Type *base)
43 {
44     if ((base->SCR & SRC_GENERAL_SCR_BT_RELEASE_M7_MASK) == 0UL)
45     {
46         base->SCR |= SRC_GENERAL_SCR_BT_RELEASE_M7_MASK;
47     }
48 }
49 
50 /*!
51  * brief Sets the reset mode of global system reset source.
52  *
53  * This function sets the selected mode of the input global system reset sources. This function will return as soon as
54  * the reset if finished.
55  *
56  * param base SRC peripheral base address.
57  * param resetSource The global system reset source. See @ref src_global_system_reset_source_t for more details.
58  * param resetMode The reset mode of each reset source. See @ref src_global_system_reset_mode_t for more details.
59  */
SRC_SetGlobalSystemResetMode(SRC_GENERAL_Type * base,src_reset_source_t resetSource,src_reset_mode_t resetMode)60 void SRC_SetGlobalSystemResetMode(SRC_GENERAL_Type *base, src_reset_source_t resetSource, src_reset_mode_t resetMode)
61 {
62     uint32_t regValue;
63 
64     regValue = base->SRMASK;
65     regValue &= ~SRC_GLOBAL_SYSTEM_RESET_BEHAVIOR_CONFIG(resetSource, SRC_GLOBAL_SYSTEM_RESET_BEHAVIOR_MASK);
66     regValue |= SRC_GLOBAL_SYSTEM_RESET_BEHAVIOR_CONFIG(resetSource, resetMode);
67 
68     base->SRMASK = regValue;
69 }
70 
71 /*!
72  * brief Set software control step for slice power on/off sequence.
73  *
74  * param base SRC peripheral base address.
75  * param step Slice power on/off sequence step. See @ref src_power_ctrl_step_t for more details.
76  */
SRC_SLICE_SoftwareControl(SRC_MIX_SLICE_Type * base,src_power_ctrl_step_t step)77 void SRC_SLICE_SoftwareControl(SRC_MIX_SLICE_Type *base, src_power_ctrl_step_t step)
78 {
79     base->AUTHEN_CTRL &= ~SRC_MIX_SLICE_AUTHEN_CTRL_LPM_MODE_MASK;
80 
81     switch (step)
82     {
83         case kSRC_PDN_EdgelockHandshake:
84             base->SLICE_SW_CTRL |= SRC_MIX_SLICE_SLICE_SW_CTRL_EDGELOCK_HDSK_SOFT_MASK;
85             while ((base->FUNC_STAT & SRC_MIX_SLICE_FUNC_STAT_EDGELOCK_HDSK_STAT_MASK) !=
86                    SRC_MIX_SLICE_FUNC_STAT_EDGELOCK_HDSK_STAT_MASK)
87             {
88             }
89             break;
90         case kSRC_PDN_IsolationOn:
91             base->SLICE_SW_CTRL |= SRC_MIX_SLICE_SLICE_SW_CTRL_ISO_ON_SOFT_MASK;
92             while ((base->FUNC_STAT & SRC_MIX_SLICE_FUNC_STAT_ISO_STAT_MASK) != SRC_MIX_SLICE_FUNC_STAT_ISO_STAT_MASK)
93             {
94             }
95             break;
96         case kSRC_PDN_ResetAssert:
97             base->SLICE_SW_CTRL |= SRC_MIX_SLICE_SLICE_SW_CTRL_RST_CTRL_SOFT_MASK;
98             while ((base->FUNC_STAT & SRC_MIX_SLICE_FUNC_STAT_RST_STAT_MASK) != 0UL)
99             {
100             }
101             break;
102         case kSRC_PDN_PowerSwitchOff:
103             base->SLICE_SW_CTRL |= SRC_MIX_SLICE_SLICE_SW_CTRL_PSW_OFF_SOFT_MASK;
104             while ((base->FUNC_STAT & SRC_MIX_SLICE_FUNC_STAT_PSW_STAT_MASK) != SRC_MIX_SLICE_FUNC_STAT_PSW_STAT_MASK)
105             {
106             }
107             break;
108         case kSRC_PUP_PowerSwitchOn:
109             base->SLICE_SW_CTRL &= ~SRC_MIX_SLICE_SLICE_SW_CTRL_PSW_OFF_SOFT_MASK;
110             while ((base->FUNC_STAT & SRC_MIX_SLICE_FUNC_STAT_PSW_STAT_MASK) != 0UL)
111             {
112             }
113             break;
114         case kSRC_PUP_ResetRelease:
115             base->SLICE_SW_CTRL &= ~SRC_MIX_SLICE_SLICE_SW_CTRL_RST_CTRL_SOFT_MASK;
116             while ((base->FUNC_STAT & SRC_MIX_SLICE_FUNC_STAT_RST_STAT_MASK) != SRC_MIX_SLICE_FUNC_STAT_RST_STAT_MASK)
117             {
118             }
119             break;
120         case kSRC_PUP_IsolationOff:
121             base->SLICE_SW_CTRL &= ~SRC_MIX_SLICE_SLICE_SW_CTRL_ISO_ON_SOFT_MASK;
122             while ((base->FUNC_STAT & SRC_MIX_SLICE_FUNC_STAT_ISO_STAT_MASK) != 0UL)
123             {
124             }
125             break;
126         case kSRC_PUP_EdgeLockHandshake:
127             base->SLICE_SW_CTRL &= ~SRC_MIX_SLICE_SLICE_SW_CTRL_EDGELOCK_HDSK_SOFT_MASK;
128             while ((base->FUNC_STAT & SRC_MIX_SLICE_FUNC_STAT_EDGELOCK_HDSK_STAT_MASK) != 0UL)
129             {
130             }
131             break;
132         default:
133             assert(false);
134             break;
135     }
136 }
137 
138 /*!
139  * brief Power on/off slice.
140  *
141  * param base SRC peripheral base address.
142  * param powerOff Used to trigger slice power on/off sequence.
143  *			   - \b true Trigger a power off sequence.
144  *			   - \b false Trigger a power on sequence.
145  */
SRC_SLICE_PowerDown(SRC_MIX_SLICE_Type * base,bool powerOff)146 void SRC_SLICE_PowerDown(SRC_MIX_SLICE_Type *base, bool powerOff)
147 {
148     base->AUTHEN_CTRL &= ~SRC_MIX_SLICE_AUTHEN_CTRL_LPM_MODE_MASK;
149 
150     if (powerOff)
151     {
152         base->SLICE_SW_CTRL |= SRC_MIX_SLICE_SLICE_SW_CTRL_PDN_SOFT_MASK;
153     }
154     else
155     {
156         base->SLICE_SW_CTRL &= ~SRC_MIX_SLICE_SLICE_SW_CTRL_PDN_SOFT_MASK;
157     }
158 }
159 
SRC_SLICE_ControlByCpuLowPowerMode(SRC_MIX_SLICE_Type * base,uint32_t domainMap,src_power_level_t level)160 void SRC_SLICE_ControlByCpuLowPowerMode(SRC_MIX_SLICE_Type *base, uint32_t domainMap, src_power_level_t level)
161 {
162     uint32_t domainIndex            = 0UL;
163     uint32_t tmp32                  = 0UL;
164     uint32_t regIndex               = 0UL;
165     volatile uint32_t *ptrMemLpmReg = NULL;
166 
167     /* Change power level for each domain. */
168     domainMap &= 0xFFFFU;
169     ptrMemLpmReg = &(base->LPM_SETTING_1);
170     for (regIndex = 0UL; regIndex < 2UL; regIndex++)
171     {
172         ptrMemLpmReg += regIndex;
173         tmp32 = *ptrMemLpmReg;
174         for (domainIndex = 0UL; domainIndex < 8UL; domainIndex++)
175         {
176             if (0UL != (domainMap & (1UL << ((regIndex * 8UL) + domainIndex))))
177             {
178                 tmp32 &= ~((uint32_t)SRC_MIX_SLICE_LPM_SETTING_1_LPM_SETTING_D0_MASK << (domainIndex * 4U));
179                 tmp32 |= ((uint32_t)SRC_MIX_SLICE_LPM_SETTING_1_LPM_SETTING_D0(level) << (domainIndex * 4U));
180             }
181         }
182         *ptrMemLpmReg = tmp32;
183     }
184 
185     /* Set control mode to CPU low power mode. */
186     base->AUTHEN_CTRL |= SRC_MIX_SLICE_AUTHEN_CTRL_LPM_MODE_MASK;
187 }
188