1 /*
2 * Copyright 2020-2021 NXP
3 * All rights reserved.
4 *
5 * SPDX-License-Identifier: BSD-3-Clause
6 */
7
8 #include "fsl_ssarc.h"
9
10 /* Component ID definition, used by tools. */
11 #ifndef FSL_COMPONENT_ID
12 #define FSL_COMPONENT_ID "platform.drivers.ssarc"
13 #endif
14
15 /*******************************************************************************
16 * Definitions
17 ******************************************************************************/
18
19 /*******************************************************************************
20 * Prototypes
21 ******************************************************************************/
22 static void SSARC_MapDescriptorsToGroup(SSARC_LP_Type *base, uint8_t groupID, uint32_t startIndex, uint32_t endIndex);
23 static void SSARC_SetGroupRestoreOrder(SSARC_LP_Type *base, uint8_t groupID, ssarc_save_restore_order_t order);
24 static void SSARC_SetGroupSaveOrder(SSARC_LP_Type *base, uint8_t groupID, ssarc_save_restore_order_t order);
25 /*******************************************************************************
26 * Variables
27 ******************************************************************************/
28
29 /*******************************************************************************
30 * Code
31 ******************************************************************************/
32
33 /*!
34 * @brief Maps the descriptors to the selected group.
35 *
36 * @note One descriptor can be mapped to different group, but please make sure
37 * one descriptor can only be mapped to one power domain.
38 *
39 * @param base SSARC_LP peripheral base address.
40 * @param groupID The index of the group. Range from 0 to 15.
41 * @param startIndex The index of the first descriptor of the group.
42 * @param endIndex The index of the last descriptor of the group.
43 */
SSARC_MapDescriptorsToGroup(SSARC_LP_Type * base,uint8_t groupID,uint32_t startIndex,uint32_t endIndex)44 static void SSARC_MapDescriptorsToGroup(SSARC_LP_Type *base, uint8_t groupID, uint32_t startIndex, uint32_t endIndex)
45 {
46 assert(groupID < SSARC_LP_DESC_CTRL0_COUNT);
47 assert((startIndex < endIndex) || (startIndex == endIndex));
48
49 base->GROUPS[groupID].DESC_CTRL0 = SSARC_LP_DESC_CTRL0_START(startIndex) | SSARC_LP_DESC_CTRL0_END(endIndex);
50 }
51
52 /*!
53 * @brief Set the order of descriptors within the group are processed when restoring register values.
54 *
55 * @param base SSARC_LP peripheral base address.
56 * @param groupID The index of the group. Range from 0 to 15.
57 * @param order The restore order.
58 */
SSARC_SetGroupRestoreOrder(SSARC_LP_Type * base,uint8_t groupID,ssarc_save_restore_order_t order)59 static void SSARC_SetGroupRestoreOrder(SSARC_LP_Type *base, uint8_t groupID, ssarc_save_restore_order_t order)
60 {
61 assert(groupID < SSARC_LP_DESC_CTRL0_COUNT);
62
63 if (order == kSSARC_ProcessFromStartToEnd)
64 {
65 base->GROUPS[groupID].DESC_CTRL0 &= ~SSARC_LP_DESC_CTRL0_RT_ORDER_MASK;
66 }
67 else
68 {
69 base->GROUPS[groupID].DESC_CTRL0 |= SSARC_LP_DESC_CTRL0_RT_ORDER_MASK;
70 }
71 }
72
73 /*!
74 * @brief Set the order of descriptors within the group are processed when saving register values.
75 *
76 * @param base SSARC_LP peripheral base address.
77 * @param groupID The index of the group. Range from 0 to 15.
78 * @param order The save order.
79 */
SSARC_SetGroupSaveOrder(SSARC_LP_Type * base,uint8_t groupID,ssarc_save_restore_order_t order)80 static void SSARC_SetGroupSaveOrder(SSARC_LP_Type *base, uint8_t groupID, ssarc_save_restore_order_t order)
81 {
82 assert(groupID < SSARC_LP_DESC_CTRL0_COUNT);
83
84 if (order == kSSARC_ProcessFromStartToEnd)
85 {
86 base->GROUPS[groupID].DESC_CTRL0 &= ~SSARC_LP_DESC_CTRL0_SV_ORDER_MASK;
87 }
88 else
89 {
90 base->GROUPS[groupID].DESC_CTRL0 |= SSARC_LP_DESC_CTRL0_SV_ORDER_MASK;
91 }
92 }
93
94 /*!
95 * brief Sets the configuration of the descriptor.
96 *
97 * param base SSARC_HP peripheral base address.
98 * param index The index of descriptor. Range from 0 to 1023.
99 * param config Pointer to the structure ssarc_descriptor_config_t. Please refer to @ref ssarc_descriptor_config_t for
100 * details.
101 */
SSARC_SetDescriptorConfig(SSARC_HP_Type * base,uint32_t index,const ssarc_descriptor_config_t * config)102 void SSARC_SetDescriptorConfig(SSARC_HP_Type *base, uint32_t index, const ssarc_descriptor_config_t *config)
103 {
104 assert(config != NULL);
105
106 uint32_t temp32 = 0UL;
107
108 /* Set the address of the register to be saved/restored. */
109 base->DESC[index].SRAM0 = config->address;
110
111 temp32 = SSARC_HP_SRAM2_TYPE(config->type) | SSARC_HP_SRAM2_SIZE(config->size);
112 temp32 |= (uint32_t)(config->operation);
113
114 base->DESC[index].SRAM2 = temp32;
115
116 /* Set the value of the register to be saved/restored. */
117 /* If the type is set as kSSARC_ReadValueWriteBack, the SRAM1 register will be
118 loaded with the value on save operation, and the data in SRAM1 register will be over-written, so
119 it is no need to set SRAM1 register in that type. */
120 if (config->type != kSSARC_ReadValueWriteBack)
121 {
122 base->DESC[index].SRAM1 = config->data;
123 }
124 }
125
126 /*!
127 * brief Init the selected group.
128 *
129 * note For the groups with the same save priority or restore priority,
130 * the save/restore operation runs in the group order.
131 *
132 * param base SSARC_LP peripheral base address.
133 * param groupID The index of the group. Range from 0 to 15.
134 * param config Pointer to the structure ssarc_group_config_t. Please refer to @ref ssarc_group_config_t for details.
135 */
SSARC_GroupInit(SSARC_LP_Type * base,uint8_t groupID,const ssarc_group_config_t * config)136 void SSARC_GroupInit(SSARC_LP_Type *base, uint8_t groupID, const ssarc_group_config_t *config)
137 {
138 assert(config != NULL);
139 assert(groupID < SSARC_LP_DESC_CTRL0_COUNT);
140
141 uint32_t temp32;
142
143 temp32 = SSARC_LP_DESC_CTRL1_POWER_DOMAIN(config->powerDomain) |
144 SSARC_LP_DESC_CTRL1_SV_PRIORITY(config->savePriority) |
145 SSARC_LP_DESC_CTRL1_RT_PRIORITY(config->restorePriority) | SSARC_LP_DESC_CTRL1_CPUD(config->cpuDomain);
146 base->GROUPS[groupID].DESC_CTRL1 = temp32;
147
148 SSARC_MapDescriptorsToGroup(base, groupID, config->startIndex, config->endIndex);
149 SSARC_SetGroupRestoreOrder(base, groupID, config->restoreOrder);
150 SSARC_SetGroupSaveOrder(base, groupID, config->saveOrder);
151
152 /* Config the highest address and the lowest address. */
153 base->GROUPS[groupID].DESC_ADDR_UP = config->highestAddress;
154 base->GROUPS[groupID].DESC_ADDR_DOWN = config->lowestAddress;
155
156 /* Enable the group. */
157 base->GROUPS[groupID].DESC_CTRL1 |= SSARC_LP_DESC_CTRL1_GP_EN_MASK;
158 }
159
160 /*!
161 * brief Triggers software request.
162 *
163 * note Each group allows software to trigger the save/restore operation without getting the request
164 * from basic power controller.
165 *
166 * param base SSARC_LP peripheral base address.
167 * param groupID The index of the group. Range from 0 to 15.
168 * param mode. Software trigger mode. Please refer to @ref ssarc_software_trigger_mode_t for details.
169 */
SSARC_TriggerSoftwareRequest(SSARC_LP_Type * base,uint8_t groupID,ssarc_software_trigger_mode_t mode)170 void SSARC_TriggerSoftwareRequest(SSARC_LP_Type *base, uint8_t groupID, ssarc_software_trigger_mode_t mode)
171 {
172 assert(groupID < SSARC_LP_DESC_CTRL0_COUNT);
173
174 base->GROUPS[groupID].DESC_CTRL1 |= (uint32_t)mode;
175
176 while (((base->GROUPS[groupID].DESC_CTRL1) & (uint32_t)mode) != 0UL)
177 {
178 }
179 }
180