fsl_pgmc.c 17 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461
  1. /*
  2. * Copyright 2019-2021, NXP
  3. * All rights reserved.
  4. *
  5. *
  6. * SPDX-License-Identifier: BSD-3-Clause
  7. */
  8. #include "fsl_pgmc.h"
  9. /*******************************************************************************
  10. * Definitions
  11. ******************************************************************************/
  12. /* Component ID definition, used by tools. */
  13. #ifndef FSL_COMPONENT_ID
  14. #define FSL_COMPONENT_ID "platform.drivers.pgmc"
  15. #endif
  16. /*!
  17. * @brief The structure of MIF signal.
  18. */
  19. typedef struct
  20. {
  21. __IO uint32_t SIGNAL; /*!< MIF MLPL control of each signal. */
  22. __IO uint32_t DELAY; /*!< MIF Delay of each signal */
  23. uint32_t RESERVED[2];
  24. } PGMC_MIF_SIGNAL_Type;
  25. /*******************************************************************************
  26. * Variables
  27. ******************************************************************************/
  28. /*******************************************************************************
  29. * Code
  30. ******************************************************************************/
  31. /*!
  32. * brief Makes the BPC module controlled by the target CPU power mode(Such as Wait mode).
  33. *
  34. * This function makes the module controlled by four typical CPU power modes, It also configs the resource domain and
  35. * set memory low power level.
  36. *
  37. * param base PGMC basic power controller base address.
  38. * param mode Target CPU power mode.
  39. * param option The pointer of @ref pgmc_bpc_cpu_power_mode_option_t structure.
  40. */
  41. void PGMC_BPC_ControlPowerDomainByCpuPowerMode(PGMC_BPC_Type *base,
  42. pgmc_cpu_mode_t mode,
  43. const pgmc_bpc_cpu_power_mode_option_t *option)
  44. {
  45. assert(option != NULL);
  46. uint32_t tmp32 = base->BPC_SSAR_SAVE_CTRL;
  47. base->BPC_MODE = PGMC_BPC_BPC_MODE_DOMAIN_ASSIGN(option->assignDomain) |
  48. PGMC_BPC_BPC_MODE_CTRL_MODE(kPGMC_ControlledByCpuPowerMode);
  49. switch (mode)
  50. {
  51. case kPGMC_RunMode:
  52. tmp32 |= PGMC_BPC_BPC_SSAR_SAVE_CTRL_SAVE_AT_RUN_MASK;
  53. break;
  54. case kPGMC_WaitMode:
  55. if (option->powerOff)
  56. {
  57. base->BPC_POWER_CTRL |= PGMC_BPC_BPC_POWER_CTRL_PWR_OFF_AT_WAIT_MASK;
  58. }
  59. tmp32 |= PGMC_BPC_BPC_SSAR_SAVE_CTRL_SAVE_AT_WAIT_MASK;
  60. break;
  61. case kPGMC_StopMode:
  62. if (option->powerOff)
  63. {
  64. base->BPC_POWER_CTRL |= PGMC_BPC_BPC_POWER_CTRL_PWR_OFF_AT_STOP_MASK;
  65. }
  66. tmp32 |= PGMC_BPC_BPC_SSAR_SAVE_CTRL_SAVE_AT_SUSPEND_MASK;
  67. break;
  68. case kPGMC_SuspendMode:
  69. if (option->powerOff)
  70. {
  71. base->BPC_POWER_CTRL |= PGMC_BPC_BPC_POWER_CTRL_PWR_OFF_AT_SUSPEND_MASK;
  72. }
  73. tmp32 |= PGMC_BPC_BPC_SSAR_SAVE_CTRL_SAVE_AT_SUSPEND_MASK;
  74. break;
  75. default:
  76. assert(false);
  77. break;
  78. }
  79. if (option->stateSave)
  80. {
  81. base->BPC_SSAR_SAVE_CTRL = tmp32;
  82. }
  83. }
  84. /*!
  85. * brief Makes the BPC module controlled by the target set points.
  86. *
  87. * This function makes the module controlled by specific set point, It also supports set memory lowe power level.
  88. *
  89. * note When setting more than one set point, use "|" between the map values in @ref _pgmc_setpoint_map.
  90. *
  91. * param base PGMC basic power controller base address.
  92. * param setPointMap Should be the OR'ed value of @ref _pgmc_setpoint_map.
  93. * param option The pointer of @ref pgmc_bpc_setpoint_mode_option_t structure.
  94. */
  95. void PGMC_BPC_ControlPowerDomainBySetPointMode(PGMC_BPC_Type *base,
  96. uint32_t setPointMap,
  97. const pgmc_bpc_setpoint_mode_option_t *option)
  98. {
  99. assert(option != NULL);
  100. setPointMap &= 0xFFFFU;
  101. base->BPC_MODE = PGMC_BPC_BPC_MODE_CTRL_MODE(kPGMC_ControlledBySetPoint);
  102. if (option->powerOff)
  103. {
  104. base->BPC_POWER_CTRL |= PGMC_BPC_BPC_POWER_CTRL_PWR_OFF_AT_SP(setPointMap);
  105. }
  106. if (option->stateSave)
  107. {
  108. base->BPC_SSAR_SAVE_CTRL = PGMC_BPC_BPC_SSAR_SAVE_CTRL_SAVE_AT_SP(setPointMap);
  109. }
  110. }
  111. /*!
  112. * brief Controls the selected power domain by software mode.
  113. *
  114. * note The function is used to control power domain when the CPU is in RUN mode.
  115. *
  116. * param base PGMC basic power controller base address.
  117. * param powerOff Power On/Off power domain in software mode.
  118. * - \b true Power off the power domain in software mode.
  119. * - \b false Power on the power domain in software mode.
  120. */
  121. void PGMC_BPC_ControlPowerDomainBySoftwareMode(PGMC_BPC_Type *base, bool powerOff)
  122. {
  123. if (powerOff)
  124. {
  125. base->BPC_POWER_CTRL |= (PGMC_BPC_BPC_POWER_CTRL_PSW_OFF_SOFT_MASK | PGMC_BPC_BPC_POWER_CTRL_ISO_ON_SOFT_MASK);
  126. }
  127. else
  128. {
  129. base->BPC_POWER_CTRL |= (PGMC_BPC_BPC_POWER_CTRL_PSW_ON_SOFT_MASK | PGMC_BPC_BPC_POWER_CTRL_ISO_OFF_SOFT_MASK);
  130. }
  131. }
  132. /*!
  133. * brief Powers off the CPC core module by the target CPU power mode(Such as Wait mode).
  134. *
  135. * param base CPC CORE module base address.
  136. * param mode Target CPU power mode.
  137. */
  138. void PGMC_CPC_CORE_PowerOffByCpuPowerMode(PGMC_CPC_Type *base, pgmc_cpu_mode_t mode)
  139. {
  140. base->CPC_CORE_MODE = PGMC_CPC_CPC_CORE_MODE_CTRL_MODE(kPGMC_ControlledByCpuPowerMode);
  141. switch (mode)
  142. {
  143. case kPGMC_RunMode:
  144. break;
  145. case kPGMC_WaitMode:
  146. base->CPC_CORE_POWER_CTRL |= PGMC_CPC_CPC_CORE_POWER_CTRL_PWR_OFF_AT_WAIT_MASK;
  147. break;
  148. case kPGMC_StopMode:
  149. base->CPC_CORE_POWER_CTRL |= PGMC_CPC_CPC_CORE_POWER_CTRL_PWR_OFF_AT_STOP_MASK;
  150. break;
  151. case kPGMC_SuspendMode:
  152. base->CPC_CORE_POWER_CTRL |= PGMC_CPC_CPC_CORE_POWER_CTRL_PWR_OFF_AT_SUSPEND_MASK;
  153. break;
  154. default:
  155. assert(false);
  156. break;
  157. }
  158. }
  159. /*!
  160. * brief Makes the CPC CACHE module controlled by the target CPU power mode(Such as Wait mode).
  161. *
  162. * This function makes the module controlled by four typical CPU power modes, it also can set memory low power level.
  163. *
  164. * param base CPC CACHE module base address.
  165. * param mode Target CPU power mode.
  166. * param memoryLowPowerLevel Memory low power level.
  167. */
  168. void PGMC_CPC_CACHE_ControlByCpuPowerMode(PGMC_CPC_Type *base,
  169. pgmc_cpu_mode_t mode,
  170. pgmc_memory_low_power_level_t memoryLowPowerLevel)
  171. {
  172. uint32_t temp32;
  173. base->CPC_CACHE_MODE = PGMC_CPC_CPC_CACHE_MODE_CTRL_MODE(kPGMC_ControlledByCpuPowerMode);
  174. temp32 = base->CPC_CACHE_CM_CTRL;
  175. switch (mode)
  176. {
  177. case kPGMC_RunMode:
  178. temp32 &= ~PGMC_CPC_CPC_CACHE_CM_CTRL_MLPL_AT_RUN_MASK;
  179. base->CPC_CACHE_CM_CTRL = temp32 | PGMC_CPC_CPC_CACHE_CM_CTRL_MLPL_AT_RUN(memoryLowPowerLevel);
  180. break;
  181. case kPGMC_WaitMode:
  182. temp32 &= ~PGMC_CPC_CPC_CACHE_CM_CTRL_MLPL_AT_WAIT_MASK;
  183. base->CPC_CACHE_CM_CTRL = temp32 | PGMC_CPC_CPC_CACHE_CM_CTRL_MLPL_AT_WAIT(memoryLowPowerLevel);
  184. break;
  185. case kPGMC_StopMode:
  186. temp32 &= ~PGMC_CPC_CPC_CACHE_CM_CTRL_MLPL_AT_STOP_MASK;
  187. base->CPC_CACHE_CM_CTRL = temp32 | PGMC_CPC_CPC_CACHE_CM_CTRL_MLPL_AT_STOP(memoryLowPowerLevel);
  188. break;
  189. case kPGMC_SuspendMode:
  190. temp32 &= ~PGMC_CPC_CPC_CACHE_CM_CTRL_MLPL_AT_SUSPEND_MASK;
  191. base->CPC_CACHE_CM_CTRL = temp32 | PGMC_CPC_CPC_CACHE_CM_CTRL_MLPL_AT_SUSPEND(memoryLowPowerLevel);
  192. break;
  193. default:
  194. assert(false);
  195. break;
  196. }
  197. }
  198. /*!
  199. * brief Makes the CPC CACHE module controlled by the target set points.
  200. *
  201. * This function makes the module controlled by specific set point, It also supports set memory lowe power level.
  202. *
  203. * note When setting more than one set point, use "|" between the map values in @ref _pgmc_setpoint_map.
  204. *
  205. * param base CPC CACHE module base address.
  206. * param setPointMap Should be the OR'ed value of @ref _pgmc_setpoint_map.
  207. * param memoryLowPowerLevel Memory low power level.
  208. */
  209. void PGMC_CPC_CACHE_ControlBySetPointMode(PGMC_CPC_Type *base,
  210. uint32_t setPointMap,
  211. pgmc_memory_low_power_level_t memoryLowPowerLevel)
  212. {
  213. uint32_t setPointIndex = 0UL;
  214. uint32_t tmp32 = 0UL;
  215. uint32_t regIndex = 0UL;
  216. volatile uint32_t *ptrMemSpCtrlReg = NULL;
  217. setPointMap &= 0xFFFFU;
  218. base->CPC_CACHE_MODE = PGMC_CPC_CPC_CACHE_MODE_CTRL_MODE(kPGMC_ControlledBySetPoint);
  219. ptrMemSpCtrlReg = &(base->CPC_CACHE_SP_CTRL_0);
  220. for (regIndex = 0UL; regIndex < 2UL; regIndex++)
  221. {
  222. ptrMemSpCtrlReg += regIndex;
  223. tmp32 = *ptrMemSpCtrlReg;
  224. for (setPointIndex = 0UL; setPointIndex < 8UL; setPointIndex++)
  225. {
  226. if (0UL != (setPointMap & (1UL << ((regIndex * 8UL) + setPointIndex))))
  227. {
  228. tmp32 &= ~((uint32_t)PGMC_CPC_CPC_CACHE_SP_CTRL_0_MLPL_AT_SP0_MASK << (setPointIndex * 4U));
  229. tmp32 |= ((uint32_t)memoryLowPowerLevel << (setPointIndex * 4U));
  230. }
  231. }
  232. *ptrMemSpCtrlReg = tmp32;
  233. }
  234. }
  235. /*!
  236. * brief Requests CPC cache module's memory low power level change by software mode.
  237. *
  238. * note If request memory low power level change, must wait the MLPL transition complete.
  239. *
  240. * param base CPC LMEM module base address.
  241. */
  242. void PGMC_CPC_CACHE_TriggerMLPLSoftwareChange(PGMC_CPC_Type *base)
  243. {
  244. base->CPC_CACHE_CM_CTRL |= PGMC_CPC_CPC_CACHE_CM_CTRL_MLPL_SOFT_MASK;
  245. /* If request software change, check the MLPL transition status. */
  246. while (0UL != ((base->CPC_CACHE_CM_CTRL) & PGMC_CPC_CPC_CACHE_CM_CTRL_MLPL_SOFT_MASK))
  247. {
  248. }
  249. }
  250. /*!
  251. * brief Makes the CPC LMEM module controlled by the target CPU power mode(Such as Wait mode).
  252. *
  253. * This function makes the module controlled by four typical CPU power modes, it also can set memory low power level.
  254. *
  255. * param base CPC LMEM module base address.
  256. * param mode Target CPU power mode.
  257. * param memoryLowPowerLevel Memory low power level.
  258. */
  259. void PGMC_CPC_LMEM_ControlByCpuPowerMode(PGMC_CPC_Type *base,
  260. pgmc_cpu_mode_t mode,
  261. pgmc_memory_low_power_level_t memoryLowPowerLevel)
  262. {
  263. uint32_t temp32;
  264. base->CPC_LMEM_MODE = PGMC_CPC_CPC_LMEM_MODE_CTRL_MODE(kPGMC_ControlledByCpuPowerMode);
  265. temp32 = base->CPC_LMEM_CM_CTRL;
  266. switch (mode)
  267. {
  268. case kPGMC_RunMode:
  269. temp32 &= ~PGMC_CPC_CPC_LMEM_CM_CTRL_MLPL_AT_RUN_MASK;
  270. base->CPC_LMEM_CM_CTRL = temp32 | PGMC_CPC_CPC_LMEM_CM_CTRL_MLPL_AT_RUN(memoryLowPowerLevel);
  271. break;
  272. case kPGMC_WaitMode:
  273. temp32 &= ~PGMC_CPC_CPC_LMEM_CM_CTRL_MLPL_AT_WAIT_MASK;
  274. base->CPC_LMEM_CM_CTRL = temp32 | PGMC_CPC_CPC_LMEM_CM_CTRL_MLPL_AT_WAIT(memoryLowPowerLevel);
  275. break;
  276. case kPGMC_StopMode:
  277. temp32 &= ~PGMC_CPC_CPC_LMEM_CM_CTRL_MLPL_AT_STOP_MASK;
  278. base->CPC_LMEM_CM_CTRL = temp32 | PGMC_CPC_CPC_LMEM_CM_CTRL_MLPL_AT_STOP(memoryLowPowerLevel);
  279. break;
  280. case kPGMC_SuspendMode:
  281. temp32 &= ~PGMC_CPC_CPC_LMEM_CM_CTRL_MLPL_AT_SUSPEND_MASK;
  282. base->CPC_LMEM_CM_CTRL = temp32 | PGMC_CPC_CPC_LMEM_CM_CTRL_MLPL_AT_SUSPEND(memoryLowPowerLevel);
  283. break;
  284. default:
  285. assert(false);
  286. break;
  287. }
  288. }
  289. /*!
  290. * brief Makes the CPC LMEM module controlled by the target set points.
  291. *
  292. * This function makes the module controlled by specific set point, It also supports set memory lowe power level.
  293. *
  294. * note When setting more than one set point, use "|" between the map values in @ref _pgmc_setpoint_map.
  295. *
  296. * param base CPC LMEM module base address.
  297. * param setPointMap Should be the OR'ed value of @ref _pgmc_setpoint_map.
  298. * param memoryLowPowerLevel Memory low power level.
  299. */
  300. void PGMC_CPC_LMEM_ControlBySetPointMode(PGMC_CPC_Type *base,
  301. uint32_t setPointMap,
  302. pgmc_memory_low_power_level_t memoryLowPowerLevel)
  303. {
  304. uint32_t setPointIndex = 0UL;
  305. uint32_t tmp32 = 0UL;
  306. uint32_t regIndex = 0UL;
  307. volatile uint32_t *ptrMemSpCtrlReg = NULL;
  308. setPointMap &= 0xFFFFU;
  309. base->CPC_LMEM_MODE = PGMC_CPC_CPC_LMEM_MODE_CTRL_MODE(kPGMC_ControlledBySetPoint);
  310. ptrMemSpCtrlReg = &(base->CPC_LMEM_SP_CTRL_0);
  311. for (regIndex = 0UL; regIndex < 2UL; regIndex++)
  312. {
  313. ptrMemSpCtrlReg += regIndex;
  314. tmp32 = *ptrMemSpCtrlReg;
  315. for (setPointIndex = 0UL; setPointIndex < 8UL; setPointIndex++)
  316. {
  317. if (0UL != (setPointMap & (1UL << ((regIndex * 8UL) + setPointIndex))))
  318. {
  319. tmp32 &= ~((uint32_t)PGMC_CPC_CPC_LMEM_SP_CTRL_0_MLPL_AT_SP0_MASK << (setPointIndex * 4U));
  320. tmp32 |= ((uint32_t)memoryLowPowerLevel << (setPointIndex * 4U));
  321. }
  322. }
  323. *ptrMemSpCtrlReg = tmp32;
  324. }
  325. }
  326. /*!
  327. * brief Requests CPC LMEM module's memory low power level change in software mode.
  328. *
  329. * note If request memory low power level change, must wait the MLPL transition complete.
  330. *
  331. * param base CPC LMEM module base address.
  332. */
  333. void PGMC_CPC_LMEM_TriggerMLPLSoftwareChange(PGMC_CPC_Type *base)
  334. {
  335. base->CPC_LMEM_CM_CTRL |= PGMC_CPC_CPC_LMEM_CM_CTRL_MLPL_SOFT_MASK;
  336. /* If request software change, check the MLPL transition status. */
  337. while (0UL != ((base->CPC_LMEM_CM_CTRL) & PGMC_CPC_CPC_LMEM_CM_CTRL_MLPL_SOFT_MASK))
  338. {
  339. }
  340. }
  341. /*!
  342. * brief Sets the behaviour of each signal(Such as Sleep signal) in MIF.
  343. *
  344. * note To control the memory low power operation, this function must be invoked after selecting the
  345. * memory low power level.
  346. * Use case:
  347. * code
  348. * PGMC_BPC_ControlPowerDomainByCpuPowerMode(PGMC_BPC0_BASE, kPGMC_WaitMode, kPGMC_CM7Core,
  349. * kPGMC_MLPLSleep, false);
  350. * PGMC_MIF_SetSignalBehaviour(PGMC_BPC0_MIF_BASE, kPGMC_MLPLSleep, kPGMC_AssertSleepSignal);
  351. * endcode
  352. *
  353. * param base PGMC MIF peripheral base address.
  354. * param memoryLevel The selected memory low power level. For details please refer to @ref
  355. * pgmc_memory_low_power_level_t.
  356. * param mask The mask of MIF signal behaviour. Should be the OR'ed value of @ref _pgmc_mif_signal_behaviour
  357. */
  358. void PGMC_MIF_SetSignalBehaviour(PGMC_MIF_Type *base, pgmc_memory_low_power_level_t memoryLevel, uint32_t mask)
  359. {
  360. uint8_t signalIndex = 0U;
  361. uint32_t temp32 = 0U;
  362. PGMC_MIF_SIGNAL_Type *MIF_SIG = (PGMC_MIF_SIGNAL_Type *)(uint32_t)(&(base->MIF_MLPL_SLEEP));
  363. for (signalIndex = 0U; signalIndex < 11U; signalIndex++)
  364. {
  365. temp32 = MIF_SIG[signalIndex].SIGNAL;
  366. temp32 &= ~(1UL << (uint32_t)memoryLevel);
  367. temp32 |= ((uint32_t)(mask & (1UL << signalIndex)) << (uint32_t)memoryLevel);
  368. MIF_SIG[signalIndex].SIGNAL = temp32;
  369. }
  370. }
  371. /*!
  372. * brief Makes the PMIC module controlled by the target CPU power mode(Such as Wait mode).
  373. *
  374. * param base PMIC module base address.
  375. * param mode Target CPU power mode.
  376. */
  377. void PGMC_PPC_ControlByCpuPowerMode(PGMC_PPC_Type *base, pgmc_cpu_mode_t mode)
  378. {
  379. base->PPC_MODE = PGMC_PPC_PPC_MODE_CTRL_MODE(kPGMC_ControlledByCpuPowerMode);
  380. switch (mode)
  381. {
  382. case kPGMC_RunMode:
  383. break;
  384. case kPGMC_WaitMode:
  385. base->PPC_STBY_CM_CTRL |= PGMC_PPC_PPC_STBY_CM_CTRL_STBY_ON_AT_WAIT_MASK;
  386. break;
  387. case kPGMC_StopMode:
  388. base->PPC_STBY_CM_CTRL |= PGMC_PPC_PPC_STBY_CM_CTRL_STBY_ON_AT_STOP_MASK;
  389. break;
  390. case kPGMC_SuspendMode:
  391. base->PPC_STBY_CM_CTRL |= PGMC_PPC_PPC_STBY_CM_CTRL_STBY_ON_AT_SUSPEND_MASK;
  392. break;
  393. default:
  394. assert(false);
  395. break;
  396. }
  397. }
  398. /*!
  399. * brief Makes the PMIC module controlled by the target set points.
  400. *
  401. * This function makes the module controlled by specific set point, It also supports PMIC standby on.
  402. *
  403. * note When setting more than one set point, use "|" between the map values in @ref _pgmc_setpoint_map.
  404. *
  405. * param base PMIC module base address.
  406. * param setPointMap Should be the OR'ed value of @ref _pgmc_setpoint_map.
  407. * param enableStandby true: PMIC standby on when system enters set point number and system is in standby mode.
  408. * false: PMIC standby on when system enters set point number
  409. */
  410. void PGMC_PPC_ControlBySetPointMode(PGMC_PPC_Type *base, uint32_t setPointMap, bool enableStandby)
  411. {
  412. setPointMap &= 0xFFFFU;
  413. base->PPC_MODE = PGMC_PPC_PPC_MODE_CTRL_MODE(kPGMC_ControlledBySetPoint);
  414. if (enableStandby)
  415. {
  416. base->PPC_STBY_SP_CTRL = (setPointMap << PGMC_PPC_PPC_STBY_SP_CTRL_STBY_ON_AT_SP_SLEEP_SHIFT);
  417. }
  418. else
  419. {
  420. base->PPC_STBY_SP_CTRL = setPointMap;
  421. }
  422. }