summaryrefslogtreecommitdiffstats
path: root/bsps/arm/imxrt/mcux-sdk/devices/MIMXRT1166/drivers/fsl_pgmc.c
diff options
context:
space:
mode:
Diffstat (limited to 'bsps/arm/imxrt/mcux-sdk/devices/MIMXRT1166/drivers/fsl_pgmc.c')
-rw-r--r--bsps/arm/imxrt/mcux-sdk/devices/MIMXRT1166/drivers/fsl_pgmc.c461
1 files changed, 461 insertions, 0 deletions
diff --git a/bsps/arm/imxrt/mcux-sdk/devices/MIMXRT1166/drivers/fsl_pgmc.c b/bsps/arm/imxrt/mcux-sdk/devices/MIMXRT1166/drivers/fsl_pgmc.c
new file mode 100644
index 0000000000..03488ee4b1
--- /dev/null
+++ b/bsps/arm/imxrt/mcux-sdk/devices/MIMXRT1166/drivers/fsl_pgmc.c
@@ -0,0 +1,461 @@
+/*
+ * Copyright 2019-2021, NXP
+ * All rights reserved.
+ *
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include "fsl_pgmc.h"
+
+/*******************************************************************************
+ * Definitions
+ ******************************************************************************/
+
+/* Component ID definition, used by tools. */
+#ifndef FSL_COMPONENT_ID
+#define FSL_COMPONENT_ID "platform.drivers.pgmc"
+#endif
+
+/*!
+ * @brief The structure of MIF signal.
+ */
+typedef struct
+{
+ __IO uint32_t SIGNAL; /*!< MIF MLPL control of each signal. */
+ __IO uint32_t DELAY; /*!< MIF Delay of each signal */
+ uint32_t RESERVED[2];
+} PGMC_MIF_SIGNAL_Type;
+
+/*******************************************************************************
+ * Variables
+ ******************************************************************************/
+
+/*******************************************************************************
+ * Code
+ ******************************************************************************/
+
+/*!
+ * brief Makes the BPC module controlled by the target CPU power mode(Such as Wait mode).
+ *
+ * This function makes the module controlled by four typical CPU power modes, It also configs the resource domain and
+ * set memory low power level.
+ *
+ * param base PGMC basic power controller base address.
+ * param mode Target CPU power mode.
+ * param option The pointer of @ref pgmc_bpc_cpu_power_mode_option_t structure.
+ */
+void PGMC_BPC_ControlPowerDomainByCpuPowerMode(PGMC_BPC_Type *base,
+ pgmc_cpu_mode_t mode,
+ const pgmc_bpc_cpu_power_mode_option_t *option)
+{
+ assert(option != NULL);
+
+ uint32_t tmp32 = base->BPC_SSAR_SAVE_CTRL;
+
+ base->BPC_MODE = PGMC_BPC_BPC_MODE_DOMAIN_ASSIGN(option->assignDomain) |
+ PGMC_BPC_BPC_MODE_CTRL_MODE(kPGMC_ControlledByCpuPowerMode);
+ switch (mode)
+ {
+ case kPGMC_RunMode:
+ tmp32 |= PGMC_BPC_BPC_SSAR_SAVE_CTRL_SAVE_AT_RUN_MASK;
+ break;
+ case kPGMC_WaitMode:
+ if (option->powerOff)
+ {
+ base->BPC_POWER_CTRL |= PGMC_BPC_BPC_POWER_CTRL_PWR_OFF_AT_WAIT_MASK;
+ }
+ tmp32 |= PGMC_BPC_BPC_SSAR_SAVE_CTRL_SAVE_AT_WAIT_MASK;
+ break;
+ case kPGMC_StopMode:
+ if (option->powerOff)
+ {
+ base->BPC_POWER_CTRL |= PGMC_BPC_BPC_POWER_CTRL_PWR_OFF_AT_STOP_MASK;
+ }
+ tmp32 |= PGMC_BPC_BPC_SSAR_SAVE_CTRL_SAVE_AT_SUSPEND_MASK;
+ break;
+ case kPGMC_SuspendMode:
+ if (option->powerOff)
+ {
+ base->BPC_POWER_CTRL |= PGMC_BPC_BPC_POWER_CTRL_PWR_OFF_AT_SUSPEND_MASK;
+ }
+ tmp32 |= PGMC_BPC_BPC_SSAR_SAVE_CTRL_SAVE_AT_SUSPEND_MASK;
+ break;
+ default:
+ assert(false);
+ break;
+ }
+
+ if (option->stateSave)
+ {
+ base->BPC_SSAR_SAVE_CTRL = tmp32;
+ }
+}
+
+/*!
+ * brief Makes the BPC module controlled by the target set points.
+ *
+ * This function makes the module controlled by specific set point, It also supports set memory lowe power level.
+ *
+ * note When setting more than one set point, use "|" between the map values in @ref _pgmc_setpoint_map.
+ *
+ * param base PGMC basic power controller base address.
+ * param setPointMap Should be the OR'ed value of @ref _pgmc_setpoint_map.
+ * param option The pointer of @ref pgmc_bpc_setpoint_mode_option_t structure.
+ */
+void PGMC_BPC_ControlPowerDomainBySetPointMode(PGMC_BPC_Type *base,
+ uint32_t setPointMap,
+ const pgmc_bpc_setpoint_mode_option_t *option)
+{
+ assert(option != NULL);
+
+ setPointMap &= 0xFFFFU;
+
+ base->BPC_MODE = PGMC_BPC_BPC_MODE_CTRL_MODE(kPGMC_ControlledBySetPoint);
+ if (option->powerOff)
+ {
+ base->BPC_POWER_CTRL |= PGMC_BPC_BPC_POWER_CTRL_PWR_OFF_AT_SP(setPointMap);
+ }
+
+ if (option->stateSave)
+ {
+ base->BPC_SSAR_SAVE_CTRL = PGMC_BPC_BPC_SSAR_SAVE_CTRL_SAVE_AT_SP(setPointMap);
+ }
+}
+
+/*!
+ * brief Controls the selected power domain by software mode.
+ *
+ * note The function is used to control power domain when the CPU is in RUN mode.
+ *
+ * param base PGMC basic power controller base address.
+ * param powerOff Power On/Off power domain in software mode.
+ * - \b true Power off the power domain in software mode.
+ * - \b false Power on the power domain in software mode.
+ */
+void PGMC_BPC_ControlPowerDomainBySoftwareMode(PGMC_BPC_Type *base, bool powerOff)
+{
+ if (powerOff)
+ {
+ base->BPC_POWER_CTRL |= (PGMC_BPC_BPC_POWER_CTRL_PSW_OFF_SOFT_MASK | PGMC_BPC_BPC_POWER_CTRL_ISO_ON_SOFT_MASK);
+ }
+ else
+ {
+ base->BPC_POWER_CTRL |= (PGMC_BPC_BPC_POWER_CTRL_PSW_ON_SOFT_MASK | PGMC_BPC_BPC_POWER_CTRL_ISO_OFF_SOFT_MASK);
+ }
+}
+
+/*!
+ * brief Powers off the CPC core module by the target CPU power mode(Such as Wait mode).
+ *
+ * param base CPC CORE module base address.
+ * param mode Target CPU power mode.
+ */
+void PGMC_CPC_CORE_PowerOffByCpuPowerMode(PGMC_CPC_Type *base, pgmc_cpu_mode_t mode)
+{
+ base->CPC_CORE_MODE = PGMC_CPC_CPC_CORE_MODE_CTRL_MODE(kPGMC_ControlledByCpuPowerMode);
+ switch (mode)
+ {
+ case kPGMC_RunMode:
+ break;
+ case kPGMC_WaitMode:
+ base->CPC_CORE_POWER_CTRL |= PGMC_CPC_CPC_CORE_POWER_CTRL_PWR_OFF_AT_WAIT_MASK;
+ break;
+ case kPGMC_StopMode:
+ base->CPC_CORE_POWER_CTRL |= PGMC_CPC_CPC_CORE_POWER_CTRL_PWR_OFF_AT_STOP_MASK;
+ break;
+ case kPGMC_SuspendMode:
+ base->CPC_CORE_POWER_CTRL |= PGMC_CPC_CPC_CORE_POWER_CTRL_PWR_OFF_AT_SUSPEND_MASK;
+ break;
+ default:
+ assert(false);
+ break;
+ }
+}
+
+/*!
+ * brief Makes the CPC CACHE module controlled by the target CPU power mode(Such as Wait mode).
+ *
+ * This function makes the module controlled by four typical CPU power modes, it also can set memory low power level.
+ *
+ * param base CPC CACHE module base address.
+ * param mode Target CPU power mode.
+ * param memoryLowPowerLevel Memory low power level.
+ */
+void PGMC_CPC_CACHE_ControlByCpuPowerMode(PGMC_CPC_Type *base,
+ pgmc_cpu_mode_t mode,
+ pgmc_memory_low_power_level_t memoryLowPowerLevel)
+{
+ uint32_t temp32;
+
+ base->CPC_CACHE_MODE = PGMC_CPC_CPC_CACHE_MODE_CTRL_MODE(kPGMC_ControlledByCpuPowerMode);
+ temp32 = base->CPC_CACHE_CM_CTRL;
+ switch (mode)
+ {
+ case kPGMC_RunMode:
+ temp32 &= ~PGMC_CPC_CPC_CACHE_CM_CTRL_MLPL_AT_RUN_MASK;
+ base->CPC_CACHE_CM_CTRL = temp32 | PGMC_CPC_CPC_CACHE_CM_CTRL_MLPL_AT_RUN(memoryLowPowerLevel);
+ break;
+ case kPGMC_WaitMode:
+ temp32 &= ~PGMC_CPC_CPC_CACHE_CM_CTRL_MLPL_AT_WAIT_MASK;
+ base->CPC_CACHE_CM_CTRL = temp32 | PGMC_CPC_CPC_CACHE_CM_CTRL_MLPL_AT_WAIT(memoryLowPowerLevel);
+ break;
+ case kPGMC_StopMode:
+ temp32 &= ~PGMC_CPC_CPC_CACHE_CM_CTRL_MLPL_AT_STOP_MASK;
+ base->CPC_CACHE_CM_CTRL = temp32 | PGMC_CPC_CPC_CACHE_CM_CTRL_MLPL_AT_STOP(memoryLowPowerLevel);
+ break;
+ case kPGMC_SuspendMode:
+ temp32 &= ~PGMC_CPC_CPC_CACHE_CM_CTRL_MLPL_AT_SUSPEND_MASK;
+ base->CPC_CACHE_CM_CTRL = temp32 | PGMC_CPC_CPC_CACHE_CM_CTRL_MLPL_AT_SUSPEND(memoryLowPowerLevel);
+ break;
+ default:
+ assert(false);
+ break;
+ }
+}
+
+/*!
+ * brief Makes the CPC CACHE module controlled by the target set points.
+ *
+ * This function makes the module controlled by specific set point, It also supports set memory lowe power level.
+ *
+ * note When setting more than one set point, use "|" between the map values in @ref _pgmc_setpoint_map.
+ *
+ * param base CPC CACHE module base address.
+ * param setPointMap Should be the OR'ed value of @ref _pgmc_setpoint_map.
+ * param memoryLowPowerLevel Memory low power level.
+ */
+void PGMC_CPC_CACHE_ControlBySetPointMode(PGMC_CPC_Type *base,
+ uint32_t setPointMap,
+ pgmc_memory_low_power_level_t memoryLowPowerLevel)
+{
+ uint32_t setPointIndex = 0UL;
+ uint32_t tmp32 = 0UL;
+ uint32_t regIndex = 0UL;
+ volatile uint32_t *ptrMemSpCtrlReg = NULL;
+
+ setPointMap &= 0xFFFFU;
+
+ base->CPC_CACHE_MODE = PGMC_CPC_CPC_CACHE_MODE_CTRL_MODE(kPGMC_ControlledBySetPoint);
+
+ ptrMemSpCtrlReg = &(base->CPC_CACHE_SP_CTRL_0);
+ for (regIndex = 0UL; regIndex < 2UL; regIndex++)
+ {
+ ptrMemSpCtrlReg += regIndex;
+ tmp32 = *ptrMemSpCtrlReg;
+ for (setPointIndex = 0UL; setPointIndex < 8UL; setPointIndex++)
+ {
+ if (0UL != (setPointMap & (1UL << ((regIndex * 8UL) + setPointIndex))))
+ {
+ tmp32 &= ~((uint32_t)PGMC_CPC_CPC_CACHE_SP_CTRL_0_MLPL_AT_SP0_MASK << (setPointIndex * 4U));
+ tmp32 |= ((uint32_t)memoryLowPowerLevel << (setPointIndex * 4U));
+ }
+ }
+ *ptrMemSpCtrlReg = tmp32;
+ }
+}
+
+/*!
+ * brief Requests CPC cache module's memory low power level change by software mode.
+ *
+ * note If request memory low power level change, must wait the MLPL transition complete.
+ *
+ * param base CPC LMEM module base address.
+ */
+void PGMC_CPC_CACHE_TriggerMLPLSoftwareChange(PGMC_CPC_Type *base)
+{
+ base->CPC_CACHE_CM_CTRL |= PGMC_CPC_CPC_CACHE_CM_CTRL_MLPL_SOFT_MASK;
+
+ /* If request software change, check the MLPL transition status. */
+ while (0UL != ((base->CPC_CACHE_CM_CTRL) & PGMC_CPC_CPC_CACHE_CM_CTRL_MLPL_SOFT_MASK))
+ {
+ }
+}
+
+/*!
+ * brief Makes the CPC LMEM module controlled by the target CPU power mode(Such as Wait mode).
+ *
+ * This function makes the module controlled by four typical CPU power modes, it also can set memory low power level.
+ *
+ * param base CPC LMEM module base address.
+ * param mode Target CPU power mode.
+ * param memoryLowPowerLevel Memory low power level.
+ */
+void PGMC_CPC_LMEM_ControlByCpuPowerMode(PGMC_CPC_Type *base,
+ pgmc_cpu_mode_t mode,
+ pgmc_memory_low_power_level_t memoryLowPowerLevel)
+{
+ uint32_t temp32;
+
+ base->CPC_LMEM_MODE = PGMC_CPC_CPC_LMEM_MODE_CTRL_MODE(kPGMC_ControlledByCpuPowerMode);
+
+ temp32 = base->CPC_LMEM_CM_CTRL;
+ switch (mode)
+ {
+ case kPGMC_RunMode:
+ temp32 &= ~PGMC_CPC_CPC_LMEM_CM_CTRL_MLPL_AT_RUN_MASK;
+ base->CPC_LMEM_CM_CTRL = temp32 | PGMC_CPC_CPC_LMEM_CM_CTRL_MLPL_AT_RUN(memoryLowPowerLevel);
+ break;
+ case kPGMC_WaitMode:
+ temp32 &= ~PGMC_CPC_CPC_LMEM_CM_CTRL_MLPL_AT_WAIT_MASK;
+ base->CPC_LMEM_CM_CTRL = temp32 | PGMC_CPC_CPC_LMEM_CM_CTRL_MLPL_AT_WAIT(memoryLowPowerLevel);
+ break;
+ case kPGMC_StopMode:
+ temp32 &= ~PGMC_CPC_CPC_LMEM_CM_CTRL_MLPL_AT_STOP_MASK;
+ base->CPC_LMEM_CM_CTRL = temp32 | PGMC_CPC_CPC_LMEM_CM_CTRL_MLPL_AT_STOP(memoryLowPowerLevel);
+ break;
+ case kPGMC_SuspendMode:
+ temp32 &= ~PGMC_CPC_CPC_LMEM_CM_CTRL_MLPL_AT_SUSPEND_MASK;
+ base->CPC_LMEM_CM_CTRL = temp32 | PGMC_CPC_CPC_LMEM_CM_CTRL_MLPL_AT_SUSPEND(memoryLowPowerLevel);
+ break;
+ default:
+ assert(false);
+ break;
+ }
+}
+
+/*!
+ * brief Makes the CPC LMEM module controlled by the target set points.
+ *
+ * This function makes the module controlled by specific set point, It also supports set memory lowe power level.
+ *
+ * note When setting more than one set point, use "|" between the map values in @ref _pgmc_setpoint_map.
+ *
+ * param base CPC LMEM module base address.
+ * param setPointMap Should be the OR'ed value of @ref _pgmc_setpoint_map.
+ * param memoryLowPowerLevel Memory low power level.
+ */
+void PGMC_CPC_LMEM_ControlBySetPointMode(PGMC_CPC_Type *base,
+ uint32_t setPointMap,
+ pgmc_memory_low_power_level_t memoryLowPowerLevel)
+{
+ uint32_t setPointIndex = 0UL;
+ uint32_t tmp32 = 0UL;
+ uint32_t regIndex = 0UL;
+ volatile uint32_t *ptrMemSpCtrlReg = NULL;
+
+ setPointMap &= 0xFFFFU;
+
+ base->CPC_LMEM_MODE = PGMC_CPC_CPC_LMEM_MODE_CTRL_MODE(kPGMC_ControlledBySetPoint);
+
+ ptrMemSpCtrlReg = &(base->CPC_LMEM_SP_CTRL_0);
+ for (regIndex = 0UL; regIndex < 2UL; regIndex++)
+ {
+ ptrMemSpCtrlReg += regIndex;
+ tmp32 = *ptrMemSpCtrlReg;
+ for (setPointIndex = 0UL; setPointIndex < 8UL; setPointIndex++)
+ {
+ if (0UL != (setPointMap & (1UL << ((regIndex * 8UL) + setPointIndex))))
+ {
+ tmp32 &= ~((uint32_t)PGMC_CPC_CPC_LMEM_SP_CTRL_0_MLPL_AT_SP0_MASK << (setPointIndex * 4U));
+ tmp32 |= ((uint32_t)memoryLowPowerLevel << (setPointIndex * 4U));
+ }
+ }
+ *ptrMemSpCtrlReg = tmp32;
+ }
+}
+
+/*!
+ * brief Requests CPC LMEM module's memory low power level change in software mode.
+ *
+ * note If request memory low power level change, must wait the MLPL transition complete.
+ *
+ * param base CPC LMEM module base address.
+ */
+void PGMC_CPC_LMEM_TriggerMLPLSoftwareChange(PGMC_CPC_Type *base)
+{
+ base->CPC_LMEM_CM_CTRL |= PGMC_CPC_CPC_LMEM_CM_CTRL_MLPL_SOFT_MASK;
+
+ /* If request software change, check the MLPL transition status. */
+ while (0UL != ((base->CPC_LMEM_CM_CTRL) & PGMC_CPC_CPC_LMEM_CM_CTRL_MLPL_SOFT_MASK))
+ {
+ }
+}
+
+/*!
+ * brief Sets the behaviour of each signal(Such as Sleep signal) in MIF.
+ *
+ * note To control the memory low power operation, this function must be invoked after selecting the
+ * memory low power level.
+ * Use case:
+ * code
+ * PGMC_BPC_ControlPowerDomainByCpuPowerMode(PGMC_BPC0_BASE, kPGMC_WaitMode, kPGMC_CM7Core,
+ * kPGMC_MLPLSleep, false);
+ * PGMC_MIF_SetSignalBehaviour(PGMC_BPC0_MIF_BASE, kPGMC_MLPLSleep, kPGMC_AssertSleepSignal);
+ * endcode
+ *
+ * param base PGMC MIF peripheral base address.
+ * param memoryLevel The selected memory low power level. For details please refer to @ref
+ * pgmc_memory_low_power_level_t.
+ * param mask The mask of MIF signal behaviour. Should be the OR'ed value of @ref _pgmc_mif_signal_behaviour
+ */
+void PGMC_MIF_SetSignalBehaviour(PGMC_MIF_Type *base, pgmc_memory_low_power_level_t memoryLevel, uint32_t mask)
+{
+ uint8_t signalIndex = 0U;
+ uint32_t temp32 = 0U;
+ PGMC_MIF_SIGNAL_Type *MIF_SIG = (PGMC_MIF_SIGNAL_Type *)(uint32_t)(&(base->MIF_MLPL_SLEEP));
+
+ for (signalIndex = 0U; signalIndex < 11U; signalIndex++)
+ {
+ temp32 = MIF_SIG[signalIndex].SIGNAL;
+ temp32 &= ~(1UL << (uint32_t)memoryLevel);
+ temp32 |= ((uint32_t)(mask & (1UL << signalIndex)) << (uint32_t)memoryLevel);
+ MIF_SIG[signalIndex].SIGNAL = temp32;
+ }
+}
+
+/*!
+ * brief Makes the PMIC module controlled by the target CPU power mode(Such as Wait mode).
+ *
+ * param base PMIC module base address.
+ * param mode Target CPU power mode.
+ */
+void PGMC_PPC_ControlByCpuPowerMode(PGMC_PPC_Type *base, pgmc_cpu_mode_t mode)
+{
+ base->PPC_MODE = PGMC_PPC_PPC_MODE_CTRL_MODE(kPGMC_ControlledByCpuPowerMode);
+ switch (mode)
+ {
+ case kPGMC_RunMode:
+ break;
+ case kPGMC_WaitMode:
+ base->PPC_STBY_CM_CTRL |= PGMC_PPC_PPC_STBY_CM_CTRL_STBY_ON_AT_WAIT_MASK;
+ break;
+ case kPGMC_StopMode:
+ base->PPC_STBY_CM_CTRL |= PGMC_PPC_PPC_STBY_CM_CTRL_STBY_ON_AT_STOP_MASK;
+ break;
+ case kPGMC_SuspendMode:
+ base->PPC_STBY_CM_CTRL |= PGMC_PPC_PPC_STBY_CM_CTRL_STBY_ON_AT_SUSPEND_MASK;
+ break;
+ default:
+ assert(false);
+ break;
+ }
+}
+
+/*!
+ * brief Makes the PMIC module controlled by the target set points.
+ *
+ * This function makes the module controlled by specific set point, It also supports PMIC standby on.
+ *
+ * note When setting more than one set point, use "|" between the map values in @ref _pgmc_setpoint_map.
+ *
+ * param base PMIC module base address.
+ * param setPointMap Should be the OR'ed value of @ref _pgmc_setpoint_map.
+ * param enableStandby true: PMIC standby on when system enters set point number and system is in standby mode.
+ * false: PMIC standby on when system enters set point number
+ */
+void PGMC_PPC_ControlBySetPointMode(PGMC_PPC_Type *base, uint32_t setPointMap, bool enableStandby)
+{
+ setPointMap &= 0xFFFFU;
+
+ base->PPC_MODE = PGMC_PPC_PPC_MODE_CTRL_MODE(kPGMC_ControlledBySetPoint);
+
+ if (enableStandby)
+ {
+ base->PPC_STBY_SP_CTRL = (setPointMap << PGMC_PPC_PPC_STBY_SP_CTRL_STBY_ON_AT_SP_SLEEP_SHIFT);
+ }
+ else
+ {
+ base->PPC_STBY_SP_CTRL = setPointMap;
+ }
+}