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