rt-thread/bsp/imxrt/libraries/MIMXRT1170/MIMXRT1176/drivers/fsl_ssarc.c

180 lines
6.6 KiB
C

/*
* Copyright 2020-2021 NXP
* All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
#include "fsl_ssarc.h"
/* Component ID definition, used by tools. */
#ifndef FSL_COMPONENT_ID
#define FSL_COMPONENT_ID "platform.drivers.ssarc"
#endif
/*******************************************************************************
* Definitions
******************************************************************************/
/*******************************************************************************
* Prototypes
******************************************************************************/
static void SSARC_MapDescriptorsToGroup(SSARC_LP_Type *base, uint8_t groupID, uint32_t startIndex, uint32_t endIndex);
static void SSARC_SetGroupRestoreOrder(SSARC_LP_Type *base, uint8_t groupID, ssarc_save_restore_order_t order);
static void SSARC_SetGroupSaveOrder(SSARC_LP_Type *base, uint8_t groupID, ssarc_save_restore_order_t order);
/*******************************************************************************
* Variables
******************************************************************************/
/*******************************************************************************
* Code
******************************************************************************/
/*!
* @brief Maps the descriptors to the selected group.
*
* @note One descriptor can be mapped to different group, but please make sure
* one descriptor can only be mapped to one power domain.
*
* @param base SSARC_LP peripheral base address.
* @param groupID The index of the group. Range from 0 to 15.
* @param startIndex The index of the first descriptor of the group.
* @param endIndex The index of the last descriptor of the group.
*/
static void SSARC_MapDescriptorsToGroup(SSARC_LP_Type *base, uint8_t groupID, uint32_t startIndex, uint32_t endIndex)
{
assert(groupID < SSARC_LP_DESC_CTRL0_COUNT);
assert((startIndex < endIndex) || (startIndex == endIndex));
base->GROUPS[groupID].DESC_CTRL0 = SSARC_LP_DESC_CTRL0_START(startIndex) | SSARC_LP_DESC_CTRL0_END(endIndex);
}
/*!
* @brief Set the order of descriptors within the group are processed when restoring register values.
*
* @param base SSARC_LP peripheral base address.
* @param groupID The index of the group. Range from 0 to 15.
* @param order The restore order.
*/
static void SSARC_SetGroupRestoreOrder(SSARC_LP_Type *base, uint8_t groupID, ssarc_save_restore_order_t order)
{
assert(groupID < SSARC_LP_DESC_CTRL0_COUNT);
if (order == kSSARC_ProcessFromStartToEnd)
{
base->GROUPS[groupID].DESC_CTRL0 &= ~SSARC_LP_DESC_CTRL0_RT_ORDER_MASK;
}
else
{
base->GROUPS[groupID].DESC_CTRL0 |= SSARC_LP_DESC_CTRL0_RT_ORDER_MASK;
}
}
/*!
* @brief Set the order of descriptors within the group are processed when saving register values.
*
* @param base SSARC_LP peripheral base address.
* @param groupID The index of the group. Range from 0 to 15.
* @param order The save order.
*/
static void SSARC_SetGroupSaveOrder(SSARC_LP_Type *base, uint8_t groupID, ssarc_save_restore_order_t order)
{
assert(groupID < SSARC_LP_DESC_CTRL0_COUNT);
if (order == kSSARC_ProcessFromStartToEnd)
{
base->GROUPS[groupID].DESC_CTRL0 &= ~SSARC_LP_DESC_CTRL0_SV_ORDER_MASK;
}
else
{
base->GROUPS[groupID].DESC_CTRL0 |= SSARC_LP_DESC_CTRL0_SV_ORDER_MASK;
}
}
/*!
* brief Sets the configuration of the descriptor.
*
* param base SSARC_HP peripheral base address.
* param index The index of descriptor. Range from 0 to 1023.
* param config Pointer to the structure ssarc_descriptor_config_t. Please refer to @ref ssarc_descriptor_config_t for
* details.
*/
void SSARC_SetDescriptorConfig(SSARC_HP_Type *base, uint32_t index, const ssarc_descriptor_config_t *config)
{
assert(config != NULL);
uint32_t temp32 = 0UL;
/* Set the address of the register to be saved/restored. */
base->DESC[index].SRAM0 = config->address;
temp32 = SSARC_HP_SRAM2_TYPE(config->type) | SSARC_HP_SRAM2_SIZE(config->size);
temp32 |= (uint32_t)(config->operation);
base->DESC[index].SRAM2 = temp32;
/* Set the value of the register to be saved/restored. */
/* If the type is set as kSSARC_ReadValueWriteBack, the SRAM1 register will be
loaded with the value on save operation, and the data in SRAM1 register will be over-written, so
it is no need to set SRAM1 register in that type. */
if (config->type != kSSARC_ReadValueWriteBack)
{
base->DESC[index].SRAM1 = config->data;
}
}
/*!
* brief Init the selected group.
*
* note For the groups with the same save priority or restore priority,
* the save/restore operation runs in the group order.
*
* param base SSARC_LP peripheral base address.
* param groupID The index of the group. Range from 0 to 15.
* param config Pointer to the structure ssarc_group_config_t. Please refer to @ref ssarc_group_config_t for details.
*/
void SSARC_GroupInit(SSARC_LP_Type *base, uint8_t groupID, const ssarc_group_config_t *config)
{
assert(config != NULL);
assert(groupID < SSARC_LP_DESC_CTRL0_COUNT);
uint32_t temp32;
temp32 = SSARC_LP_DESC_CTRL1_POWER_DOMAIN(config->powerDomain) |
SSARC_LP_DESC_CTRL1_SV_PRIORITY(config->savePriority) |
SSARC_LP_DESC_CTRL1_RT_PRIORITY(config->restorePriority) | SSARC_LP_DESC_CTRL1_CPUD(config->cpuDomain);
base->GROUPS[groupID].DESC_CTRL1 = temp32;
SSARC_MapDescriptorsToGroup(base, groupID, config->startIndex, config->endIndex);
SSARC_SetGroupRestoreOrder(base, groupID, config->restoreOrder);
SSARC_SetGroupSaveOrder(base, groupID, config->saveOrder);
/* Config the highest address and the lowest address. */
base->GROUPS[groupID].DESC_ADDR_UP = config->highestAddress;
base->GROUPS[groupID].DESC_ADDR_DOWN = config->lowestAddress;
/* Enable the group. */
base->GROUPS[groupID].DESC_CTRL1 |= SSARC_LP_DESC_CTRL1_GP_EN_MASK;
}
/*!
* brief Triggers software request.
*
* note Each group allows software to trigger the save/restore operation without getting the request
* from basic power controller.
*
* param base SSARC_LP peripheral base address.
* param groupID The index of the group. Range from 0 to 15.
* param mode. Software trigger mode. Please refer to @ref ssarc_software_trigger_mode_t for details.
*/
void SSARC_TriggerSoftwareRequest(SSARC_LP_Type *base, uint8_t groupID, ssarc_software_trigger_mode_t mode)
{
assert(groupID < SSARC_LP_DESC_CTRL0_COUNT);
base->GROUPS[groupID].DESC_CTRL1 |= (uint32_t)mode;
while (((base->GROUPS[groupID].DESC_CTRL1) & (uint32_t)mode) != 0UL)
{
}
}