1 /*
2 * Copyright 2017-2020, 2022 NXP
3 * All rights reserved.
4 *
5 * SPDX-License-Identifier: BSD-3-Clause
6 */
7
8 #include "fsl_rdc_sema42.h"
9
10 /******************************************************************************
11 * Definitions
12 *****************************************************************************/
13
14 /* Component ID definition, used by tools. */
15 #ifndef FSL_COMPONENT_ID
16 #define FSL_COMPONENT_ID "platform.drivers.rdc_sema42"
17 #endif
18
19 /* The first number write to RSTGDP when reset RDC_SEMA42 gate. */
20 #define RDC_SEMA42_GATE_RESET_PATTERN_1 (0xE2U)
21 /* The second number write to RSTGDP when reset RDC_SEMA42 gate. */
22 #define RDC_SEMA42_GATE_RESET_PATTERN_2 (0x1DU)
23
24 #if !defined(RDC_SEMAPHORE_GATE_COUNT)
25 /* Compatible remap. */
26 #define RDC_SEMAPHORE_GATE_LDOM(x) RDC_SEMAPHORE_GATE0_LDOM(x)
27 #define RDC_SEMAPHORE_GATE_GTFSM(x) RDC_SEMAPHORE_GATE0_GTFSM(x)
28 #define RDC_SEMAPHORE_GATE_LDOM_MASK RDC_SEMAPHORE_GATE0_LDOM_MASK
29 #define RDC_SEMAPHORE_GATE_LDOM_SHIFT RDC_SEMAPHORE_GATE0_LDOM_SHIFT
30 #endif
31
32 /*******************************************************************************
33 * Prototypes
34 ******************************************************************************/
35
36 /*!
37 * @brief Get instance number for RDC_SEMA42 module.
38 *
39 * @param base RDC_SEMA42 peripheral base address.
40 */
41 uint32_t RDC_SEMA42_GetInstance(RDC_SEMAPHORE_Type *base);
42
43 /*******************************************************************************
44 * Variables
45 ******************************************************************************/
46
47 /*! @brief Pointers to sema42 bases for each instance. */
48 static RDC_SEMAPHORE_Type *const s_sema42Bases[] = RDC_SEMAPHORE_BASE_PTRS;
49
50 #if !(defined(FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) && FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL)
51 #if defined(RDC_SEMA42_CLOCKS)
52 /*! @brief Pointers to sema42 clocks for each instance. */
53 static const clock_ip_name_t s_sema42Clocks[] = RDC_SEMA42_CLOCKS;
54 #endif
55 #endif /* FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL */
56
57 /******************************************************************************
58 * CODE
59 *****************************************************************************/
60
RDC_SEMA42_GetInstance(RDC_SEMAPHORE_Type * base)61 uint32_t RDC_SEMA42_GetInstance(RDC_SEMAPHORE_Type *base)
62 {
63 uint32_t instance;
64
65 /* Find the instance index from base address mappings. */
66 for (instance = 0; instance < ARRAY_SIZE(s_sema42Bases); instance++)
67 {
68 if (s_sema42Bases[instance] == base)
69 {
70 break;
71 }
72 }
73
74 assert(instance < ARRAY_SIZE(s_sema42Bases));
75
76 return instance;
77 }
78
79 /*!
80 * brief Initializes the RDC_SEMA42 module.
81 *
82 * This function initializes the RDC_SEMA42 module. It only enables the clock but does
83 * not reset the gates because the module might be used by other processors
84 * at the same time. To reset the gates, call either RDC_SEMA42_ResetGate or
85 * RDC_SEMA42_ResetAllGates function.
86 *
87 * param base RDC_SEMA42 peripheral base address.
88 */
RDC_SEMA42_Init(RDC_SEMAPHORE_Type * base)89 void RDC_SEMA42_Init(RDC_SEMAPHORE_Type *base)
90 {
91 #if !(defined(FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) && FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL)
92 #if defined(RDC_SEMA42_CLOCKS)
93 CLOCK_EnableClock(s_sema42Clocks[RDC_SEMA42_GetInstance(base)]);
94 #endif
95 #endif /* FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL */
96 }
97
98 /*!
99 * brief De-initializes the RDC_SEMA42 module.
100 *
101 * This function de-initializes the RDC_SEMA42 module. It only disables the clock.
102 *
103 * param base RDC_SEMA42 peripheral base address.
104 */
RDC_SEMA42_Deinit(RDC_SEMAPHORE_Type * base)105 void RDC_SEMA42_Deinit(RDC_SEMAPHORE_Type *base)
106 {
107 #if !(defined(FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) && FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL)
108 #if defined(RDC_SEMA42_CLOCKS)
109 CLOCK_DisableClock(s_sema42Clocks[RDC_SEMA42_GetInstance(base)]);
110 #endif
111 #endif /* FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL */
112 }
113
114 /*!
115 * brief Tries to lock the RDC_SEMA42 gate.
116 *
117 * This function tries to lock the specific RDC_SEMA42 gate. If the gate has been
118 * locked by another processor, this function returns an error code.
119 *
120 * param base RDC_SEMA42 peripheral base address.
121 * param gateNum Gate number to lock.
122 * param masterIndex Current processor master index.
123 * param domainId Current processor domain ID.
124 *
125 * retval kStatus_Success Lock the sema42 gate successfully.
126 * retval kStatus_Failed Sema42 gate has been locked by another processor.
127 */
RDC_SEMA42_TryLock(RDC_SEMAPHORE_Type * base,uint8_t gateNum,uint8_t masterIndex,uint8_t domainId)128 status_t RDC_SEMA42_TryLock(RDC_SEMAPHORE_Type *base, uint8_t gateNum, uint8_t masterIndex, uint8_t domainId)
129 {
130 assert(gateNum < RDC_SEMA42_GATE_COUNT);
131
132 status_t status = kStatus_Success;
133 uint8_t regGate;
134
135 ++masterIndex;
136
137 regGate = (uint8_t)(RDC_SEMAPHORE_GATE_LDOM(domainId) | RDC_SEMAPHORE_GATE_GTFSM(masterIndex));
138
139 /* Try to lock. */
140 RDC_SEMA42_GATEn(base, gateNum) = masterIndex;
141
142 /* Check locked or not. */
143 if (regGate != RDC_SEMA42_GATEn(base, gateNum))
144 {
145 status = kStatus_Fail;
146 }
147
148 return status;
149 }
150
151 /*!
152 * brief Locks the RDC_SEMA42 gate.
153 *
154 * This function locks the specific RDC_SEMA42 gate. If the gate has been
155 * locked by other processors, this function waits until it is unlocked and then
156 * lock it.
157 *
158 * param base RDC_SEMA42 peripheral base address.
159 * param gateNum Gate number to lock.
160 * param masterIndex Current processor master index.
161 * param domainId Current processor domain ID.
162 */
RDC_SEMA42_Lock(RDC_SEMAPHORE_Type * base,uint8_t gateNum,uint8_t masterIndex,uint8_t domainId)163 void RDC_SEMA42_Lock(RDC_SEMAPHORE_Type *base, uint8_t gateNum, uint8_t masterIndex, uint8_t domainId)
164 {
165 while (kStatus_Success != RDC_SEMA42_TryLock(base, gateNum, masterIndex, domainId))
166 {
167 }
168 }
169
170 /*!
171 * brief Gets which domain has currently locked the gate.
172 *
173 * param base RDC_SEMA42 peripheral base address.
174 * param gateNum Gate number.
175 *
176 * return Return -1 if the gate is not locked by any domain, otherwise return the
177 * domain ID.
178 */
RDC_SEMA42_GetLockDomainID(RDC_SEMAPHORE_Type * base,uint8_t gateNum)179 int32_t RDC_SEMA42_GetLockDomainID(RDC_SEMAPHORE_Type *base, uint8_t gateNum)
180 {
181 assert(gateNum < RDC_SEMA42_GATE_COUNT);
182
183 int32_t ret;
184 uint8_t regGate = RDC_SEMA42_GATEn(base, gateNum);
185
186 /* Current gate is not locked. */
187 if (0U == (regGate & RDC_SEMAPHORE_GATE_GTFSM_MASK))
188 {
189 ret = -1;
190 }
191 else
192 {
193 ret = (int32_t)((uint8_t)((regGate & RDC_SEMAPHORE_GATE_LDOM_MASK) >> RDC_SEMAPHORE_GATE_LDOM_SHIFT));
194 }
195
196 return ret;
197 }
198
199 /*!
200 * brief Resets the RDC_SEMA42 gate to an unlocked status.
201 *
202 * This function resets a RDC_SEMA42 gate to an unlocked status.
203 *
204 * param base RDC_SEMA42 peripheral base address.
205 * param gateNum Gate number.
206 *
207 * retval kStatus_Success RDC_SEMA42 gate is reset successfully.
208 * retval kStatus_Failed Some other reset process is ongoing.
209 */
RDC_SEMA42_ResetGate(RDC_SEMAPHORE_Type * base,uint8_t gateNum)210 status_t RDC_SEMA42_ResetGate(RDC_SEMAPHORE_Type *base, uint8_t gateNum)
211 {
212 status_t status;
213
214 /*
215 * Reset all gates if gateNum >= RDC_SEMA42_GATE_NUM_RESET_ALL
216 * Reset specific gate if gateNum < RDC_SEMA42_GATE_COUNT
217 */
218
219 /* Check whether some reset is ongoing. */
220 if (0U != (base->RSTGT_R & RDC_SEMAPHORE_RSTGT_R_RSTGSM_MASK))
221 {
222 status = kStatus_Fail;
223 }
224 else
225 {
226 /* First step. */
227 base->RSTGT_W = RDC_SEMAPHORE_RSTGT_W_RSTGDP(RDC_SEMA42_GATE_RESET_PATTERN_1);
228 /* Second step. */
229 base->RSTGT_W =
230 RDC_SEMAPHORE_RSTGT_W_RSTGDP(RDC_SEMA42_GATE_RESET_PATTERN_2) | RDC_SEMAPHORE_RSTGT_W_RSTGTN(gateNum);
231
232 status = kStatus_Success;
233 }
234
235 return status;
236 }
237