1 /*
2  * Copyright 2020-2023 NXP
3  *
4  * SPDX-License-Identifier: BSD-3-Clause
5  */
6 /**
7 *   @file       Power_Ip_MC_ME.c
8 *   @version    3.0.0
9 *
10 *   @brief   POWER driver implementations.
11 *   @details POWER driver implementations.
12 *
13 *   @addtogroup POWER_DRIVER Power Ip Driver
14 *   @{
15 */
16 
17 
18 #ifdef __cplusplus
19 extern "C"{
20 #endif
21 
22 
23 
24 
25 
26 /*==================================================================================================
27                                          INCLUDE FILES
28  1) system and project includes
29  2) needed interfaces from external units
30  3) internal and external interfaces from this unit
31 ==================================================================================================*/
32 #include "Power_Ip_Private.h"
33 #include "Power_Ip_MC_ME.h"
34 #include "Power_Ip_CortexM7.h"
35 
36 #if (defined(POWER_IP_ENABLE_USER_MODE_SUPPORT) && (STD_ON == POWER_IP_ENABLE_USER_MODE_SUPPORT))
37   #if (defined(MCAL_MC_ME_REG_PROT_AVAILABLE))
38     #if (STD_ON == MCAL_MC_ME_REG_PROT_AVAILABLE)
39       #define USER_MODE_REG_PROT_ENABLED      (STD_ON)
40       #include "RegLockMacros.h"
41     #endif /* (STD_ON == MCAL_MC_ME_REG_PROT_AVAILABLE) */
42   #endif
43 #endif /* (STD_ON == POWER_IP_ENABLE_USER_MODE_SUPPORT) */
44 
45 
46 /*==================================================================================================
47                                SOURCE FILE VERSION INFORMATION
48 ==================================================================================================*/
49 #define POWER_IP_MC_ME_VENDOR_ID_C                      43
50 #define POWER_IP_MC_ME_AR_RELEASE_MAJOR_VERSION_C       4
51 #define POWER_IP_MC_ME_AR_RELEASE_MINOR_VERSION_C       7
52 #define POWER_IP_MC_ME_AR_RELEASE_REVISION_VERSION_C    0
53 #define POWER_IP_MC_ME_SW_MAJOR_VERSION_C               3
54 #define POWER_IP_MC_ME_SW_MINOR_VERSION_C               0
55 #define POWER_IP_MC_ME_SW_PATCH_VERSION_C               0
56 
57 /*==================================================================================================
58 *                                     FILE VERSION CHECKS
59 ==================================================================================================*/
60 /* Check if Power_Ip_MC_ME.c file and Power_Ip_Private.h file are of the same vendor */
61 #if (POWER_IP_MC_ME_VENDOR_ID_C != POWER_IP_PRIVATE_VENDOR_ID)
62     #error "Power_Ip_MC_ME.c and Power_Ip_Private.h have different vendor ids"
63 #endif
64 
65 /* Check if Power_Ip_MC_ME.c file and Power_Ip_Private.h file are of the same Autosar version */
66 #if ((POWER_IP_MC_ME_AR_RELEASE_MAJOR_VERSION_C != POWER_IP_PRIVATE_AR_RELEASE_MAJOR_VERSION) || \
67      (POWER_IP_MC_ME_AR_RELEASE_MINOR_VERSION_C != POWER_IP_PRIVATE_AR_RELEASE_MINOR_VERSION) || \
68      (POWER_IP_MC_ME_AR_RELEASE_REVISION_VERSION_C != POWER_IP_PRIVATE_AR_RELEASE_REVISION_VERSION) \
69     )
70     #error "AutoSar Version Numbers of Power_Ip_MC_ME.c and Power_Ip_Private.h are different"
71 #endif
72 
73 /* Check if Power_Ip_MC_ME.c file and Power_Ip_Private.h file are of the same Software version */
74 #if ((POWER_IP_MC_ME_SW_MAJOR_VERSION_C != POWER_IP_PRIVATE_SW_MAJOR_VERSION) || \
75      (POWER_IP_MC_ME_SW_MINOR_VERSION_C != POWER_IP_PRIVATE_SW_MINOR_VERSION) || \
76      (POWER_IP_MC_ME_SW_PATCH_VERSION_C != POWER_IP_PRIVATE_SW_PATCH_VERSION) \
77     )
78     #error "Software Version Numbers of Power_Ip_MC_ME.c and Power_Ip_Private.h are different"
79 #endif
80 
81 /* Check if Power_Ip_MC_ME.c file and Power_Ip_CortexM7.h file are of the same vendor */
82 #if (POWER_IP_MC_ME_VENDOR_ID_C != POWER_IP_CORTEXM7_VENDOR_ID)
83     #error "Power_Ip_MC_ME.c and Power_Ip_CortexM7.h have different vendor ids"
84 #endif
85 
86 /* Check if Power_Ip_MC_ME.c file and Power_Ip_CortexM7.h file are of the same Autosar version */
87 #if ((POWER_IP_MC_ME_AR_RELEASE_MAJOR_VERSION_C != POWER_IP_CORTEXM7_AR_RELEASE_MAJOR_VERSION) || \
88      (POWER_IP_MC_ME_AR_RELEASE_MINOR_VERSION_C != POWER_IP_CORTEXM7_AR_RELEASE_MINOR_VERSION) || \
89      (POWER_IP_MC_ME_AR_RELEASE_REVISION_VERSION_C != POWER_IP_CORTEXM7_AR_RELEASE_REVISION_VERSION) \
90     )
91     #error "AutoSar Version Numbers of Power_Ip_MC_ME.c and Power_Ip_CortexM7.h are different"
92 #endif
93 
94 /* Check if Power_Ip_MC_ME.c file and Power_Ip_CortexM7.h file are of the same Software version */
95 #if ((POWER_IP_MC_ME_SW_MAJOR_VERSION_C != POWER_IP_CORTEXM7_SW_MAJOR_VERSION) || \
96      (POWER_IP_MC_ME_SW_MINOR_VERSION_C != POWER_IP_CORTEXM7_SW_MINOR_VERSION) || \
97      (POWER_IP_MC_ME_SW_PATCH_VERSION_C != POWER_IP_CORTEXM7_SW_PATCH_VERSION) \
98     )
99     #error "Software Version Numbers of Power_Ip_MC_ME.c and Power_Ip_CortexM7.h are different"
100 #endif
101 
102 /* Check if Power_Ip_MC_ME.c file and Power_Ip_MC_ME.h file are of the same vendor */
103 #if (POWER_IP_MC_ME_VENDOR_ID_C != POWER_IP_MC_ME_VENDOR_ID)
104     #error "Power_Ip_MC_ME.c and Power_Ip_MC_ME.h have different vendor ids"
105 #endif
106 
107 /* Check if Power_Ip_MC_ME.c file and Power_Ip_MC_ME.h file are of the same Autosar version */
108 #if ((POWER_IP_MC_ME_AR_RELEASE_MAJOR_VERSION_C != POWER_IP_MC_ME_AR_RELEASE_MAJOR_VERSION) || \
109      (POWER_IP_MC_ME_AR_RELEASE_MINOR_VERSION_C != POWER_IP_MC_ME_AR_RELEASE_MINOR_VERSION) || \
110      (POWER_IP_MC_ME_AR_RELEASE_REVISION_VERSION_C != POWER_IP_MC_ME_AR_RELEASE_REVISION_VERSION) \
111     )
112     #error "AutoSar Version Numbers of Power_Ip_MC_ME.c and Power_Ip_MC_ME.h are different"
113 #endif
114 
115 /* Check if Power_Ip_MC_ME.c file and Power_Ip_MC_ME.h file are of the same Software version */
116 #if ((POWER_IP_MC_ME_SW_MAJOR_VERSION_C != POWER_IP_MC_ME_SW_MAJOR_VERSION) || \
117      (POWER_IP_MC_ME_SW_MINOR_VERSION_C != POWER_IP_MC_ME_SW_MINOR_VERSION) || \
118      (POWER_IP_MC_ME_SW_PATCH_VERSION_C != POWER_IP_MC_ME_SW_PATCH_VERSION) \
119     )
120     #error "Software Version Numbers of Power_Ip_MC_ME.c and Power_Ip_MC_ME.h are different"
121 #endif
122 
123 #if (defined(POWER_IP_ENABLE_USER_MODE_SUPPORT) && (STD_ON == POWER_IP_ENABLE_USER_MODE_SUPPORT))
124   #if (defined(MCAL_MC_ME_REG_PROT_AVAILABLE))
125     #if (STD_ON == MCAL_MC_ME_REG_PROT_AVAILABLE)
126         #ifndef DISABLE_MCAL_INTERMODULE_ASR_CHECK
127             /* Check if Power_Ip_MC_ME.c file and RegLockMacros.h file are of the same Autosar version */
128             #if ((POWER_IP_MC_ME_AR_RELEASE_MAJOR_VERSION_C    != REGLOCKMACROS_AR_RELEASE_MAJOR_VERSION) || \
129                 (POWER_IP_MC_ME_AR_RELEASE_MINOR_VERSION_C    != REGLOCKMACROS_AR_RELEASE_MINOR_VERSION))
130                 #error "AutoSar Version Numbers of Power_Ip_MC_ME.c and RegLockMacros.h are different"
131             #endif
132         #endif
133     #endif /* (STD_ON == MCAL_MC_ME_REG_PROT_AVAILABLE) */
134   #endif
135 #endif /* (STD_ON == POWER_IP_ENABLE_USER_MODE_SUPPORT) */
136 /*==================================================================================================
137                           LOCAL TYPEDEFS (STRUCTURES, UNIONS, ENUMS)
138 ==================================================================================================*/
139 
140 
141 /*==================================================================================================
142                                        LOCAL MACROS
143 ==================================================================================================*/
144 
145 
146 /*==================================================================================================
147                                        LOCAL CONSTANTS
148 ==================================================================================================*/
149 
150 
151 /*==================================================================================================
152                                        LOCAL VARIABLES
153 ==================================================================================================*/
154 #define MCU_START_SEC_VAR_INIT_UNSPECIFIED
155 
156 #include "Mcu_MemMap.h"
157 
158 static Power_Ip_MC_ME_Type * Power_Ip_pxMC_ME = (Power_Ip_MC_ME_Type *)IP_MC_ME_BASE;
159 
160 #define MCU_STOP_SEC_VAR_INIT_UNSPECIFIED
161 
162 #include "Mcu_MemMap.h"
163 /*==================================================================================================
164                                        GLOBAL CONSTANTS
165 ==================================================================================================*/
166 
167 
168 /*==================================================================================================
169                                        GLOBAL VARIABLES
170 ==================================================================================================*/
171 
172 
173 /*==================================================================================================
174                                    LOCAL FUNCTION PROTOTYPES
175 ==================================================================================================*/
176 #define MCU_START_SEC_CODE
177 
178 #include "Mcu_MemMap.h"
179 
180 
181 static inline void Power_Ip_MC_ME_WriteControlKeys(void);
182 static inline void Power_Ip_MC_ME_TriggerModeUpdate(void);
183 
184 static inline void Power_Ip_MC_ME_TriggerPartitionUpdate(uint32 TriggerMask, uint8 PartitionIndex);
185 #ifdef POWER_IP_MC_ME_COFB_SUPPORT
186 #if (POWER_IP_MC_ME_COFB_SUPPORT == STD_ON)
187 static inline void Power_Ip_MC_ME_TriggerCofbUpdate(uint8 PartitionIndex);
188 #endif
189 #endif
190 static inline void Power_Ip_MC_ME_TriggerCoreUpdate(uint8 PartitionIndex, uint8 CoreIndex);
191 
192 static void Power_Ip_MC_ME_ConfigurePartitionClock(const Power_Ip_MC_ME_PartitionConfigType * PartitionConfigPtr);
193 #ifdef POWER_IP_MC_ME_COFB_SUPPORT
194 #if (POWER_IP_MC_ME_COFB_SUPPORT == STD_ON)
195 static void Power_Ip_MC_ME_ConfigureCOFB   ( const Power_Ip_MC_ME_CofbConfigType * CofbConfigPtr,
196                                              uint8 PartitionIndex
197                                             );
198 #endif
199 #endif
200 static void Power_Ip_MC_ME_ConfigureCore(const Power_Ip_MC_ME_CoreConfigType * CoreConfigPtr,
201                                          uint8 PartitionIndex
202                                          );
203 
204 /*==================================================================================================
205                                        LOCAL FUNCTIONS
206 ==================================================================================================*/
207 /**
208 * @brief            This function triggers the hardware processes of MC_ME.
209 * @details          This function writes the key 0x5AF0 and the inverted key
210 *                   0xA50F to the Control Key Register (MC_ME_CTL_KEY).
211 *
212 * @param[in]        void
213 *
214 * @return           void
215 *
216 */
Power_Ip_MC_ME_WriteControlKeys(void)217 static inline void Power_Ip_MC_ME_WriteControlKeys(void)
218 {
219     /* Starting the hardware processes */
220 
221     /* Write key to MC_ME_CTL_KEY */
222     Power_Ip_pxMC_ME->CTL_KEY = MC_ME_CTL_KEY_KEY(MC_ME_CTL_KEY_DIRECT_KEY_U32);
223 
224     /* Write inverted key to MC_ME_CTL_KEY */
225     Power_Ip_pxMC_ME->CTL_KEY = MC_ME_CTL_KEY_KEY(MC_ME_CTL_KEY_INVERTED_KEY_U32);
226 }
227 
228 /**
229 * @brief            This function triggers a mode update.
230 * @details          This function triggers a mode update by writing to the
231 *                   corresponding MC_ME_MODE_UPD register.
232 *
233 * @param[in]        void
234 *
235 * @return           void
236 *
237 */
Power_Ip_MC_ME_TriggerModeUpdate(void)238 static inline void Power_Ip_MC_ME_TriggerModeUpdate(void)
239 {
240     Power_Ip_pxMC_ME->MODE_UPD = MC_ME_MODE_UPD_MODE_UPD(MC_ME_MODE_UPD_MODE_UPD_MASK);
241 
242     Power_Ip_MC_ME_WriteControlKeys();
243 }
244 
245 /**
246 * @brief            This function triggers a partition update.
247 * @details          This function triggers a partition update based on the value of TriggerMask
248 *                   by writing to the corresponding MC_ME_PRTNx_PUPD register.
249 *
250 * @param[in]        TriggerMask      Mask containing the process updates to be triggered.
251 * @param[in]        PartitionIndex    Index of the partition to be updated.
252 *
253 * @return           void
254 *
255 */
Power_Ip_MC_ME_TriggerPartitionUpdate(uint32 TriggerMask,uint8 PartitionIndex)256 static inline void Power_Ip_MC_ME_TriggerPartitionUpdate(   uint32 TriggerMask,
257                                                             uint8 PartitionIndex
258                                                         )
259 {
260     uint32 TempValue = 0U;
261 
262     TempValue = Power_Ip_pxMC_ME->McMePrtnArray[PartitionIndex].PRTN_PUPD;
263     TempValue &= ~TriggerMask;
264     TempValue |= TriggerMask;
265     Power_Ip_pxMC_ME->McMePrtnArray[PartitionIndex].PRTN_PUPD = TempValue;
266 
267     Power_Ip_MC_ME_WriteControlKeys();
268 }
269 
270 #ifdef POWER_IP_MC_ME_COFB_SUPPORT
271 #if (POWER_IP_MC_ME_COFB_SUPPORT == STD_ON)
272 /**
273 * @brief            This function triggers a COFB update.
274 * @details          This function triggers a COFB update by writing to
275 *                   the corresponding MC_ME_PRTNx_PUPD register.
276 *
277 * @param[in]        PartitionIndex    Index of the partition (in which the COFB set resides) to be updated.
278 *
279 * @return           void
280 *
281 */
Power_Ip_MC_ME_TriggerCofbUpdate(uint8 PartitionIndex)282 static inline void Power_Ip_MC_ME_TriggerCofbUpdate(uint8 PartitionIndex)
283 {
284     uint32 TempValue = 0U;
285 
286     TempValue = Power_Ip_pxMC_ME->McMePrtnArray[PartitionIndex].PRTN_PUPD;
287     TempValue &= (~MC_ME_PRTN0_PUPD_PCUD_MASK);
288     TempValue |= (MC_ME_PRTNX_PUPD_PCUD_TRIG_U32 & MC_ME_PRTN0_PUPD_PCUD_MASK);
289     Power_Ip_pxMC_ME->McMePrtnArray[PartitionIndex].PRTN_PUPD = TempValue;
290 
291     Power_Ip_MC_ME_WriteControlKeys();
292 }
293 #endif
294 #endif
295 
296 /**
297 * @brief            This function triggers a core update.
298 * @details          This function triggers a core update by writing to the corresponding MC_ME_PRTNx_COREx_PUPD register.
299 *
300 * @param[in]        PartitionIndex    Index of the partition to be updated.
301 * @param[in]        CoreIndex         Index of the core (within the partition) to be updated.
302 *
303 * @return           void
304 *
305 */
Power_Ip_MC_ME_TriggerCoreUpdate(uint8 PartitionIndex,uint8 CoreIndex)306 static inline void Power_Ip_MC_ME_TriggerCoreUpdate(uint8 PartitionIndex, uint8 CoreIndex)
307 {
308     uint32 TempValue = 0U;
309 
310     TempValue = Power_Ip_pxMC_ME->McMePrtnArray[PartitionIndex].McMePrtnCoreArray[CoreIndex].PRTN_CORE_PUPD;
311     TempValue &= ~MC_ME_PRTN0_CORE0_PUPD_CCUPD_MASK;
312     TempValue |= (MC_ME_PRTNX_COREX_PUPD_CCUPD_TRIG_U32 & MC_ME_PRTN0_CORE0_PUPD_CCUPD_MASK);
313     Power_Ip_pxMC_ME->McMePrtnArray[PartitionIndex].McMePrtnCoreArray[CoreIndex].PRTN_CORE_PUPD = TempValue;
314 
315     Power_Ip_MC_ME_WriteControlKeys();
316 }
317 
318 /**
319 * @brief            This function configures Partition clock enable.
320 * @details          Configures the processes and waits until the updates have finished.
321 *
322 * @param[in]        PartitionConfigPtr   Pointer to a Partition configuration structure
323 *                   (member of 'Power_Ip_MC_ME_ModeConfigType' struct).
324 *
325 * @return           void
326 *
327 */
Power_Ip_MC_ME_ConfigurePartitionClock(const Power_Ip_MC_ME_PartitionConfigType * PartitionConfigPtr)328 static void Power_Ip_MC_ME_ConfigurePartitionClock(const Power_Ip_MC_ME_PartitionConfigType * PartitionConfigPtr)
329 {
330     uint32 TempValue = 0U;
331     uint32 PartitionConfig      = PartitionConfigPtr->PartitionPconfRegValue;
332     uint32 PartitionTriggerMask = PartitionConfigPtr->PartitionTriggerMask;
333     uint32 PartitionStatus;
334     uint32 StartTime;
335     uint32 ElapsedTime;
336     uint32 TimeoutTicks;
337     boolean TimeoutOccurred = FALSE;
338     uint8 PartitionIndex = PartitionConfigPtr->PartitionIndex;
339 
340     if (MC_ME_PRTNX_PUPD_PCUD_TRIG_U32 == (PartitionTriggerMask & MC_ME_PRTN0_PUPD_PCUD_MASK))
341     {
342         /* Write the new configuration for PRTNx_PCONF[PCE]. */
343         TempValue = Power_Ip_pxMC_ME->McMePrtnArray[PartitionIndex].PRTN_PCONF;
344         TempValue &= ~MC_ME_PRTN0_PCONF_PCE_MASK;
345         TempValue |= (PartitionConfig & MC_ME_PRTN0_PCONF_PCE_MASK);
346         Power_Ip_pxMC_ME->McMePrtnArray[PartitionIndex].PRTN_PCONF = TempValue;
347 
348         /* Trigger the update in hardware. */
349         Power_Ip_MC_ME_TriggerPartitionUpdate(MC_ME_PRTN0_PUPD_PCUD_MASK, PartitionIndex);
350 
351         /* Wait until the update has finished. */
352         Power_Ip_StartTimeout(&StartTime, &ElapsedTime, &TimeoutTicks, POWER_IP_TIMEOUT_VALUE_US);
353         do
354         {
355             TimeoutOccurred = Power_Ip_TimeoutExpired(&StartTime, &ElapsedTime, TimeoutTicks);
356 
357             PartitionStatus = Power_Ip_pxMC_ME->McMePrtnArray[PartitionIndex].PRTN_STAT;
358         } while ( ((PartitionStatus & MC_ME_PRTN0_STAT_PCS_MASK) != (PartitionConfig & MC_ME_PRTN0_PCONF_PCE_MASK)) && (!TimeoutOccurred) );
359         /* timeout notification */
360         if (TimeoutOccurred)
361         {
362             Power_Ip_ReportPowerErrors(POWER_IP_REPORT_TIMEOUT_ERROR, POWER_IP_ERR_CODE_RESERVED);
363         }
364     }
365 }
366 
367 
368 #ifdef POWER_IP_MC_ME_COFB_SUPPORT
369 #if (POWER_IP_MC_ME_COFB_SUPPORT == STD_ON)
370 /**
371 * @brief            This function configures a given COFB set.
372 * @details          Configures the blocks within the given COFB set and wait until the updates have finished.
373 *
374 * @param[in]        CofbConfigPtr    Pointer to a COFB set configuration structure
375 *                   (member of 'Power_Ip_MC_ME_PartitionConfigType' struct).
376 * @param[in]        PartitionIndex        Index of the partition in which the COFB set resides.
377 *
378 * @return           void
379 *
380 */
Power_Ip_MC_ME_ConfigureCOFB(const Power_Ip_MC_ME_CofbConfigType * CofbConfigPtr,uint8 PartitionIndex)381 static void Power_Ip_MC_ME_ConfigureCOFB(const Power_Ip_MC_ME_CofbConfigType * CofbConfigPtr, uint8 PartitionIndex)
382 {
383     uint32 PeripheralsConfig   = CofbConfigPtr->CofbClkenRegValue;
384     uint32 PeripheralsToUpdate = CofbConfigPtr->CofbBlocksToUpdateMask;
385     uint32 PeripheralsStatus;
386     uint32 StartTime;
387     uint32 ElapsedTime;
388     uint32 TimeoutTicks;
389     boolean TimeoutOccurred = FALSE;
390     uint8 CofbIndex = CofbConfigPtr->CofbIndex;
391 
392     /* Write the new configuration for the COFB set. */
393     Power_Ip_pxMC_ME->McMePrtnArray[PartitionIndex].PRTN_COFB_CLKEN[CofbIndex] = PeripheralsConfig;
394 
395     /* Trigger the update in hardware. */
396     Power_Ip_MC_ME_TriggerCofbUpdate(PartitionIndex);
397 
398 #ifdef POWER_IP_MC_ME_PRTN2_COFB0_STAT_RESERVED
399 #if (POWER_IP_MC_ME_PRTN2_COFB0_STAT_RESERVED == STD_ON)
400     if ((uint8)2U != PartitionIndex)
401     {
402 #endif
403 #endif
404         /* Wait until the update has finished. */
405         Power_Ip_StartTimeout(&StartTime, &ElapsedTime, &TimeoutTicks, POWER_IP_TIMEOUT_VALUE_US);
406         do
407         {
408             TimeoutOccurred = Power_Ip_TimeoutExpired(&StartTime, &ElapsedTime, TimeoutTicks);
409 
410             PeripheralsStatus = Power_Ip_pxMC_ME->McMePrtnArray[PartitionIndex].PRTN_COFB_STAT[CofbIndex];
411         } while ( (PeripheralsConfig != (PeripheralsStatus & PeripheralsToUpdate)) && (!TimeoutOccurred) );
412         /* timeout notification */
413         if (TimeoutOccurred)
414         {
415             Power_Ip_ReportPowerErrors(POWER_IP_REPORT_TIMEOUT_ERROR, POWER_IP_ERR_CODE_RESERVED);
416         }
417 #ifdef POWER_IP_MC_ME_PRTN2_COFB0_STAT_RESERVED
418 #if (POWER_IP_MC_ME_PRTN2_COFB0_STAT_RESERVED == STD_ON)
419     }
420 #endif
421 #endif
422 }
423 #endif
424 #endif
425 
426 /**
427 * @brief            This function configures a given core.
428 * @details          Configures the core within the given partition and waits until the updates have finished.
429 *
430 * @param[in]        CoreConfigPtr    Pointer to a core configuration structure
431 *                   (member of 'Power_Ip_MC_ME_PartitionConfigType' struct).
432 * @param[in]        PartitionIndex        Index of the partition in which the core resides.
433 *
434 * @return           void
435 *
436 */
Power_Ip_MC_ME_ConfigureCore(const Power_Ip_MC_ME_CoreConfigType * CoreConfigPtr,uint8 PartitionIndex)437 static void Power_Ip_MC_ME_ConfigureCore(const Power_Ip_MC_ME_CoreConfigType * CoreConfigPtr,
438                                          uint8 PartitionIndex
439                                          )
440 {
441     uint32 CoreConfig = CoreConfigPtr->CorePconfRegValue;
442     uint32 CoreStatus;
443     uint32 StartTime;
444     uint32 ElapsedTime;
445     uint32 TimeoutTicks;
446     boolean TimeoutOccurred = FALSE;
447     uint8 CoreIndex = CoreConfigPtr->CoreIndex;
448 
449     if (MC_ME_PRTNX_COREX_PCONF_CCE_DIS_U32 == (CoreConfigPtr->CorePconfRegValue & MC_ME_PRTN0_CORE0_PCONF_CCE_MASK))
450     {
451         /* Wait until WFI is set */
452         Power_Ip_StartTimeout(&StartTime, &ElapsedTime, &TimeoutTicks, POWER_IP_TIMEOUT_VALUE_US);
453         do
454         {
455             TimeoutOccurred = Power_Ip_TimeoutExpired(&StartTime, &ElapsedTime, TimeoutTicks);
456 
457             CoreStatus = Power_Ip_pxMC_ME->McMePrtnArray[PartitionIndex].McMePrtnCoreArray[CoreIndex].PRTN_CORE_STAT;
458         } while ( (MC_ME_PRTNX_COREX_STAT_WFI_EXECUTED_U32 != (CoreStatus & MC_ME_PRTN0_CORE0_STAT_WFI_MASK)) && (!TimeoutOccurred) );
459         /* timeout notification */
460         if (TimeoutOccurred)
461         {
462             Power_Ip_ReportPowerErrors(POWER_IP_REPORT_TIMEOUT_ERROR, POWER_IP_ERR_CODE_RESERVED);
463         }
464     }
465 #if (defined(POWER_IP_CONFIGURE_CADDRN))
466   #if (POWER_IP_CONFIGURE_CADDRN == STD_ON)
467     else
468     {
469         /* Set the boot address for the core */
470         Power_Ip_pxMC_ME->McMePrtnArray[PartitionIndex].McMePrtnCoreArray[CoreIndex].PRTN_CORE_ADDR = (uint32) CoreConfigPtr->CoreBootAddress;
471     }
472   #endif
473 #endif
474 
475     if (!TimeoutOccurred)
476     {
477         /* Write the new configuration for the core. */
478         Power_Ip_pxMC_ME->McMePrtnArray[PartitionIndex].McMePrtnCoreArray[CoreIndex].PRTN_CORE_PCONF = CoreConfig;
479 
480         /* Trigger the update in hardware */
481         Power_Ip_MC_ME_TriggerCoreUpdate(PartitionIndex, CoreIndex);
482 
483         /* Wait until the update has finished. */
484         Power_Ip_StartTimeout(&StartTime, &ElapsedTime, &TimeoutTicks, POWER_IP_TIMEOUT_VALUE_US);
485         do
486         {
487             TimeoutOccurred = Power_Ip_TimeoutExpired(&StartTime, &ElapsedTime, TimeoutTicks);
488 
489             CoreStatus = Power_Ip_pxMC_ME->McMePrtnArray[PartitionIndex].McMePrtnCoreArray[CoreIndex].PRTN_CORE_STAT;
490         } while ( ((CoreStatus & MC_ME_PRTN0_CORE0_STAT_CCS_MASK) != (CoreConfig & MC_ME_PRTN0_CORE0_PCONF_CCE_MASK)) && (!TimeoutOccurred) );
491         /* timeout notification */
492         if (TimeoutOccurred)
493         {
494             Power_Ip_ReportPowerErrors(POWER_IP_REPORT_TIMEOUT_ERROR, POWER_IP_ERR_CODE_RESERVED);
495         }
496     }
497 }
498 
499 /*==================================================================================================
500                                        GLOBAL FUNCTIONS
501 ==================================================================================================*/
502 
503 #if (defined(POWER_IP_ENABLE_USER_MODE_SUPPORT) && (STD_ON == POWER_IP_ENABLE_USER_MODE_SUPPORT))
504   #if (defined(MCAL_MC_ME_REG_PROT_AVAILABLE))
505     #if (STD_ON == MCAL_MC_ME_REG_PROT_AVAILABLE)
506 /**
507 * @brief            This function will enable writing in User mode by configuring REG_PROT
508 */
Power_Ip_MC_ME_SetUserAccessAllowed(void)509 void Power_Ip_MC_ME_SetUserAccessAllowed(void)
510 {
511 #if (defined(IP_MC_ME_BASE))
512     SET_USER_ACCESS_ALLOWED(IP_MC_ME_BASE, MC_ME_PROT_MEM_U32);
513 #endif
514 }
515     #endif /* (STD_ON == MCAL_MC_ME_REG_PROT_AVAILABLE) */
516   #endif
517 #endif /* (STD_ON == POWER_IP_ENABLE_USER_MODE_SUPPORT) */
518 
519 /**
520 * @brief            This function initializes the mode structure.
521 * @details          This function initializes the mode structure by configuring the MC_ME module.
522 *                   The target mode is requested by accessing the ME_MCTL register with the required
523 *                   keys. This mode transition request by software must be a valid request
524 *                   satisfying a set of pre-defined rules to initiate the process. In the case of
525 *                   mode transitions occurring because of hardware events such as a reset, a SAFE
526 *                   mode request, or interrupt requests and wakeup events to exit from low-power
527 *                   modes, the TARGET_MODE bit field of the ME_MCTL register is automatically
528 *                   updated with the appropriate target mode.
529 *
530 * @param[in]        ModeConfigPtr   Pointer to MC_ME configuration structure
531 *                   (member of 'ModeConfigType' struct).
532 *
533 * @return           void
534 *
535 */
Power_Ip_MC_ME_ConfigCoreCOFBClock(const Power_Ip_MC_ME_ModeConfigType * ModeConfigPtr)536 void Power_Ip_MC_ME_ConfigCoreCOFBClock(const Power_Ip_MC_ME_ModeConfigType * ModeConfigPtr)
537 {
538     const Power_Ip_MC_ME_PartitionConfigType *TempPartitionConfig = NULL_PTR;
539     uint8 PartitionIndex;
540 #ifdef POWER_IP_MC_ME_COFB_SUPPORT
541 #if (POWER_IP_MC_ME_COFB_SUPPORT == STD_ON)
542     uint8 CofbIndex;
543 #endif
544 #endif
545     uint8 CoreIndex;
546 
547     for (PartitionIndex = 0U; PartitionIndex < POWER_IP_MAX_NUMBER_OF_PARTITIONS; ++PartitionIndex)
548     {
549         TempPartitionConfig = &(*ModeConfigPtr->ArrayPartitionConfigPtr)[PartitionIndex];
550 
551         if ( TRUE == TempPartitionConfig->PartitionUnderMcuControl )
552         {
553 #ifdef POWER_IP_MC_ME_COFB_SUPPORT
554 #if (POWER_IP_MC_ME_COFB_SUPPORT == STD_ON)
555             for (CofbIndex = 0U; CofbIndex < TempPartitionConfig->NumberOfCofbs; ++CofbIndex)
556             {
557                 if ( TRUE == (*TempPartitionConfig->ArrayPartitionCofbConfigPtr)[CofbIndex].CofbUnderMcuControl )
558                 {
559                     Power_Ip_MC_ME_ConfigureCOFB(&(*TempPartitionConfig->ArrayPartitionCofbConfigPtr)[CofbIndex], TempPartitionConfig->PartitionIndex);
560                 }
561             }
562 #endif
563 #endif
564             for (CoreIndex = 0U; CoreIndex < TempPartitionConfig->NumberOfCores; ++CoreIndex)
565             {
566                 if ( TRUE == (*TempPartitionConfig->ArrayPartitionCoreConfigPtr)[CoreIndex].CoreUnderMcuControl )
567                 {
568                     Power_Ip_MC_ME_ConfigureCore(&(*TempPartitionConfig->ArrayPartitionCoreConfigPtr)[CoreIndex], TempPartitionConfig->PartitionIndex);
569                 }
570             }
571         }
572     }
573 }
574 
575 /**
576 * @brief            This function Enable Partition Clock.
577 * @details          This function enable partition clock by configuring the MC_ME_PRTNx_PCONF[PCE] module.
578 *
579 * @param[in]        ModeConfigPtr   Pointer to MC_ME configuration structure
580 *                   (member of 'ModeConfigType' struct).
581 *
582 * @return           void
583 *
584 */
Power_Ip_MC_ME_EnablePartitionClock(const Power_Ip_MC_ME_ModeConfigType * ModeConfigPtr)585 void Power_Ip_MC_ME_EnablePartitionClock(const Power_Ip_MC_ME_ModeConfigType * ModeConfigPtr)
586 {
587     const Power_Ip_MC_ME_PartitionConfigType *TempPartitionConfig = NULL_PTR;
588     uint8 PartitionIndex;
589 
590     for (PartitionIndex = 0U; PartitionIndex < POWER_IP_MAX_NUMBER_OF_PARTITIONS; ++PartitionIndex)
591     {
592         TempPartitionConfig = &(*ModeConfigPtr->ArrayPartitionConfigPtr)[PartitionIndex];
593 
594         if ( TRUE == TempPartitionConfig->PartitionUnderMcuControl )
595         {
596             if ( TRUE == TempPartitionConfig->PartitionPowerUnderMcuControl )
597             {
598                 /* The partition must be enabled before configuring its COFBs and Cores */
599                 if (MC_ME_PRTNX_PCONF_PCE_EN_U32 == (TempPartitionConfig->PartitionPconfRegValue & MC_ME_PRTN0_PCONF_PCE_MASK))
600                 {
601                     Power_Ip_MC_ME_ConfigurePartitionClock(TempPartitionConfig);
602 #ifdef POWER_IP_LOCKSTEP_CTRL_SUPPORT
603   #if (POWER_IP_LOCKSTEP_CTRL_SUPPORT == STD_ON)
604                     if (0U == PartitionIndex)
605                     {
606                         Power_Ip_pxMC_ME->McMePrtnArray[PartitionIndex].CORE_LOCKSTEP = MC_ME_PRTN0_CORE_LOCKSTEP_LS2(ModeConfigPtr->CoreLockStepCtrl);
607                     }
608   #endif
609 #endif
610                 }
611             }
612         }
613     }
614 }
615 
616 /**
617 * @brief            This function Disable Partition Clock.
618 * @details          This function disable partition clock by configuring the MC_ME_PRTNx_PCONF[PCE] module.
619 *
620 * @param[in]        ModeConfigPtr   Pointer to MC_ME configuration structure
621 *                   (member of 'ModeConfigType' struct).
622 *
623 * @return           void
624 *
625 */
Power_Ip_MC_ME_DisablePartitionClock(const Power_Ip_MC_ME_ModeConfigType * ModeConfigPtr)626 void Power_Ip_MC_ME_DisablePartitionClock(const Power_Ip_MC_ME_ModeConfigType * ModeConfigPtr)
627 {
628     const Power_Ip_MC_ME_PartitionConfigType *TempPartitionConfig = NULL_PTR;
629     uint8 PartitionIndex;
630 
631     for (PartitionIndex = 0U; PartitionIndex < POWER_IP_MAX_NUMBER_OF_PARTITIONS; ++PartitionIndex)
632     {
633         TempPartitionConfig = &(*ModeConfigPtr->ArrayPartitionConfigPtr)[PartitionIndex];
634 
635         if ( TRUE == TempPartitionConfig->PartitionUnderMcuControl )
636         {
637             if ( TRUE == TempPartitionConfig->PartitionPowerUnderMcuControl )
638             {
639                 /* The partition must be disabled after configuring its COFBs and Cores */
640                 if (MC_ME_PRTNX_PCONF_PCE_DIS_U32 == (TempPartitionConfig->PartitionPconfRegValue & MC_ME_PRTN0_PCONF_PCE_MASK))
641                 {
642                     Power_Ip_MC_ME_ConfigurePartitionClock(TempPartitionConfig);
643                 }
644             }
645         }
646     }
647 }
648 
649 
650 /**
651 * @brief            This function triggers a reset event (destructive or functional) for the SoC.
652 * @details          This function triggers a reset event (destructive or functional) for the SoC.
653 *
654 * @return           Status of the previous mode.
655 *
656 */
Power_Ip_MC_ME_SocTriggerResetEvent(Power_Ip_PowerModeType PowerMode)657 void Power_Ip_MC_ME_SocTriggerResetEvent(Power_Ip_PowerModeType PowerMode)
658 {
659     if (POWER_IP_DEST_RESET_MODE == PowerMode)
660     {
661         /* Makes a request to trigger a Destructive Reset Event */
662         Power_Ip_pxMC_ME->MODE_CONF=MC_ME_MODE_CONF(MC_ME_MODE_CONF_DEST_RST_MASK);
663     }
664     else if (POWER_IP_FUNC_RESET_MODE == PowerMode)
665     {
666         /* Makes a request to trigger a Functional Reset Event */
667         Power_Ip_pxMC_ME->MODE_CONF=MC_ME_MODE_CONF(MC_ME_MODE_CONF_FUNC_RST_MASK);
668     }
669     else
670     {
671         /* Should never happen. Throw an error. */
672     }
673 
674     /* Trigger the update in hardware */
675     Power_Ip_MC_ME_TriggerModeUpdate();
676 }
677 
678 #if (defined(POWER_IP_ENTER_LOW_POWER_MODE))
679   #if (POWER_IP_ENTER_LOW_POWER_MODE == STD_ON)
680 /**
681 * @brief            This function will transition a core to Standby mode.
682 * @details          This function will transition a core to Standby mode.
683 *
684 * @param[in]        ModeConfigPtr   Pointer to mode configuration structure.
685 *
686 * @return           void
687 *
688 */
Power_Ip_MC_ME_CoreStandbyEntry(const Power_Ip_ModeConfigType * ModeConfigPtr)689 void Power_Ip_MC_ME_CoreStandbyEntry(const Power_Ip_ModeConfigType * ModeConfigPtr)
690 {
691 #ifdef MCAL_PLATFORM_ARM
692     /* Finish/Retire outstanding instructions */
693     MCAL_DATA_SYNC_BARRIER();
694 #endif
695 
696 #ifdef POWER_IP_SLEEPONEXIT_SUPPORT
697 #if (POWER_IP_SLEEPONEXIT_SUPPORT == STD_ON)
698     if (FALSE != ModeConfigPtr->SleepOnExit)
699     {
700         /* Enable Sleep On Exit */
701         Call_Power_Ip_CM7_EnableSleepOnExit();
702     }
703 #endif
704 #endif
705     /* Execute WFI */
706     EXECUTE_WAIT();
707 
708 #ifdef MCAL_PLATFORM_ARM
709     /* Finish/Retire outstanding instructions */
710     MCAL_DATA_SYNC_BARRIER();
711 #endif
712 
713 }
714   #endif /* (POWER_IP_ENTER_LOW_POWER_MODE == STD_ON) */
715 #endif
716 
717 #if (defined(POWER_IP_ENTER_LOW_POWER_MODE))
718   #if (POWER_IP_ENTER_LOW_POWER_MODE == STD_ON)
719 /**
720 * @brief            This function will transition the SoC to Standby mode.
721 * @details          This function will transition the SoC to Standby mode.
722 *
723 * @param[in]        ModeConfigPtr   Pointer to mode configuration structure.
724 *
725 * @return           void
726 *
727 */
Power_Ip_MC_ME_SocStandbyEntry(const Power_Ip_ModeConfigType * ModeConfigPtr)728 void Power_Ip_MC_ME_SocStandbyEntry(const Power_Ip_ModeConfigType * ModeConfigPtr)
729 {
730     /* Program MC_ME for valid main core id */
731     Power_Ip_pxMC_ME->MAIN_COREID = ModeConfigPtr->McMeModeConfigPtr->MainCoreIdRegValue;
732 
733 #ifdef MCAL_PLATFORM_ARM
734     /* Finish/Retire outstanding instructions */
735     MCAL_DATA_SYNC_BARRIER();
736 #endif
737 
738     /* Makes a request to go to Standby mode */
739     Power_Ip_pxMC_ME->MODE_CONF = MC_ME_MODE_CONF(MC_ME_MODE_CONF_STANDBY_MASK);
740 
741     /* Trigger the update in hardware */
742     Power_Ip_MC_ME_TriggerModeUpdate();
743 
744 #ifdef MCAL_PLATFORM_ARM
745     /* Finish/Retire outstanding instructions */
746     MCAL_DATA_SYNC_BARRIER();
747 #endif
748 
749 #ifdef POWER_IP_SLEEPONEXIT_SUPPORT
750 #if (POWER_IP_SLEEPONEXIT_SUPPORT == STD_ON)
751     if (FALSE != ModeConfigPtr->SleepOnExit)
752     {
753         /* Enable Sleep On Exit */
754         Call_Power_Ip_CM7_EnableSleepOnExit();
755     }
756 #endif
757 #endif
758     /* Execute WFI */
759     EXECUTE_WAIT();
760 
761 }
762   #endif /* (POWER_IP_ENTER_LOW_POWER_MODE == STD_ON) */
763 #endif
764 
765 #if (defined(POWER_IP_ENTER_LOW_POWER_MODE))
766   #if (POWER_IP_ENTER_LOW_POWER_MODE == STD_ON)
767 /**
768 * @brief            This function returns the previous mode.
769 * @details          This function returns the previous mode.
770 *
771 * @return           Status of the previous mode.
772 *
773 */
Power_Ip_MC_ME_GetPreviousMode(void)774 Power_Ip_PowerModeType Power_Ip_MC_ME_GetPreviousMode(void)
775 {
776     Power_Ip_PowerModeType PrevMode;
777 
778     if (MC_ME_MODE_STAT_PREV_MODE_STANDBY_U32 == (Power_Ip_pxMC_ME->MODE_STAT & MC_ME_MODE_STAT_PREV_MODE_MASK))
779     {
780         PrevMode = POWER_IP_SOC_STANDBY_MODE;
781     }
782     else
783     {
784         PrevMode = POWER_IP_RESET_MODE;
785     }
786 
787     return PrevMode;
788 }
789   #endif /* (POWER_IP_ENTER_LOW_POWER_MODE == STD_ON) */
790 #endif
791 
792 #define MCU_STOP_SEC_CODE
793 #include "Mcu_MemMap.h"
794 
795 
796 #ifdef __cplusplus
797 }
798 #endif
799 
800 /** @} */
801