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