1 /*
2 * Copyright (c) 2015, Freescale Semiconductor, Inc.
3 * Copyright 2016-2017 NXP
4 * All rights reserved.
5 *
6 * SPDX-License-Identifier: BSD-3-Clause
7 */
8
9 #include "fsl_mu.h"
10
11 /*******************************************************************************
12 * Variables
13 ******************************************************************************/
14 #if !(defined(FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) && FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL)
15 /*! @brief Pointers to mu clocks for each instance. */
16 static const clock_ip_name_t s_muClocks[] = MU_CLOCKS;
17 #endif /* FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL */
18 /*! @brief Pointers to mu bases for each instance. */
19 static MU_Type *const s_muBases[] = MU_BASE_PTRS;
20
21 /******************************************************************************
22 * Code
23 *****************************************************************************/
MU_GetInstance(MU_Type * base)24 static uint32_t MU_GetInstance(MU_Type *base)
25 {
26 uint32_t instance;
27
28 /* Find the instance index from base address mappings. */
29 for (instance = 0; instance < (sizeof(s_muBases)/sizeof(s_muBases[0])); instance++)
30 {
31 if (s_muBases[instance] == base)
32 {
33 break;
34 }
35 }
36
37 assert(instance < (sizeof(s_muBases)/sizeof(s_muBases[0])));
38
39 return instance;
40 }
41
MU_Init(MU_Type * base)42 void MU_Init(MU_Type *base)
43 {
44 #if !(defined(FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) && FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL)
45 CLOCK_EnableClock(s_muClocks[MU_GetInstance(base)]);
46 #endif /* FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL */
47 }
48
MU_Deinit(MU_Type * base)49 void MU_Deinit(MU_Type *base)
50 {
51 #if !(defined(FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) && FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL)
52 CLOCK_DisableClock(s_muClocks[MU_GetInstance(base)]);
53 #endif /* FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL */
54 }
55
MU_SendMsg(MU_Type * base,uint32_t regIndex,uint32_t msg)56 void MU_SendMsg(MU_Type *base, uint32_t regIndex, uint32_t msg)
57 {
58 assert(regIndex < MU_TR_COUNT);
59
60 /* Wait TX register to be empty. */
61 while (!(base->SR & (kMU_Tx0EmptyFlag >> regIndex)))
62 {
63 }
64
65 base->TR[regIndex] = msg;
66 }
67
MU_ReceiveMsg(MU_Type * base,uint32_t regIndex)68 uint32_t MU_ReceiveMsg(MU_Type *base, uint32_t regIndex)
69 {
70 assert(regIndex < MU_TR_COUNT);
71
72 /* Wait RX register to be full. */
73 while (!(base->SR & (kMU_Rx0FullFlag >> regIndex)))
74 {
75 }
76
77 return base->RR[regIndex];
78 }
79
MU_SetFlags(MU_Type * base,uint32_t flags)80 void MU_SetFlags(MU_Type *base, uint32_t flags)
81 {
82 /* Wait for update finished. */
83 while (base->SR & MU_SR_FUP_MASK)
84 {
85 }
86
87 MU_SetFlagsNonBlocking(base, flags);
88 }
89
MU_TriggerInterrupts(MU_Type * base,uint32_t mask)90 status_t MU_TriggerInterrupts(MU_Type *base, uint32_t mask)
91 {
92 uint32_t reg = base->CR;
93
94 /* Previous interrupt has been accepted. */
95 if (!(reg & mask))
96 {
97 /* All interrupts have been accepted, trigger now. */
98 reg = (reg & ~(MU_CR_GIRn_MASK | MU_CR_NMI_MASK)) | mask;
99 base->CR = reg;
100 return kStatus_Success;
101 }
102 else
103 {
104 return kStatus_Fail;
105 }
106 }
107
MU_BootCoreB(MU_Type * base,mu_core_boot_mode_t mode)108 void MU_BootCoreB(MU_Type *base, mu_core_boot_mode_t mode)
109 {
110 #if (defined(FSL_FEATURE_MU_HAS_RESET_INT) && FSL_FEATURE_MU_HAS_RESET_INT)
111 /* Clean the reset de-assert pending flag. */
112 base->SR = MU_SR_RDIP_MASK;
113 #endif
114
115 #if (defined(FSL_FEATURE_MU_HAS_CCR) && FSL_FEATURE_MU_HAS_CCR)
116 uint32_t reg = base->CCR;
117
118 reg = (reg & ~(MU_CCR_HR_MASK | MU_CCR_RSTH_MASK | MU_CCR_BOOT_MASK)) | MU_CCR_BOOT(mode);
119
120 base->CCR = reg;
121 #else
122 uint32_t reg = base->CR;
123
124 reg = (reg & ~((MU_CR_GIRn_MASK | MU_CR_NMI_MASK) | MU_CR_HR_MASK | MU_CR_RSTH_MASK | MU_CR_BBOOT_MASK)) | MU_CR_BBOOT(mode);
125
126 base->CR = reg;
127 #endif
128
129 #if (defined(FSL_FEATURE_MU_HAS_RESET_INT) && FSL_FEATURE_MU_HAS_RESET_INT)
130 /* Wait for coming out of reset. */
131 while (!(base->SR & MU_SR_RDIP_MASK))
132 {
133 }
134 #endif
135 }
136
MU_BootOtherCore(MU_Type * base,mu_core_boot_mode_t mode)137 void MU_BootOtherCore(MU_Type *base, mu_core_boot_mode_t mode)
138 {
139 /*
140 * MU_BootOtherCore and MU_BootCoreB are the same, MU_BootCoreB is kept
141 * for compatible with older platforms.
142 */
143 MU_BootCoreB(base, mode);
144 }
145
146 #if (defined(FSL_FEATURE_MU_HAS_CCR) && FSL_FEATURE_MU_HAS_CCR)
MU_HardwareResetOtherCore(MU_Type * base,bool waitReset,bool holdReset,mu_core_boot_mode_t bootMode)147 void MU_HardwareResetOtherCore(MU_Type *base, bool waitReset, bool holdReset, mu_core_boot_mode_t bootMode)
148 {
149 volatile uint32_t sr = 0;
150 uint32_t ccr = base->CCR & ~(MU_CCR_HR_MASK | MU_CCR_RSTH_MASK | MU_CCR_BOOT_MASK);
151
152 ccr |= MU_CCR_BOOT(bootMode);
153
154 if (holdReset)
155 {
156 ccr |= MU_CCR_RSTH_MASK;
157 }
158
159 /* Clean the reset assert pending flag. */
160 sr = (MU_SR_RAIP_MASK | MU_SR_RDIP_MASK);
161 base->SR = sr;
162
163 /* Set CCR[HR] to trigger hardware reset. */
164 base->CCR = ccr | MU_CCR_HR_MASK;
165
166 /* If don't wait the other core enters reset, return directly. */
167 if (!waitReset)
168 {
169 return;
170 }
171
172 /* Wait for the other core go to reset. */
173 while (!(base->SR & MU_SR_RAIP_MASK))
174 {
175 }
176
177 if (!holdReset)
178 {
179 /* Clear CCR[HR]. */
180 base->CCR = ccr;
181
182 /* Wait for the other core out of reset. */
183 while (!(base->SR & MU_SR_RDIP_MASK))
184 {
185 }
186 }
187 }
188 #else
MU_HardwareResetOtherCore(MU_Type * base,bool waitReset,bool holdReset,mu_core_boot_mode_t bootMode)189 void MU_HardwareResetOtherCore(MU_Type *base, bool waitReset, bool holdReset, mu_core_boot_mode_t bootMode)
190 {
191 volatile uint32_t sr = 0;
192 uint32_t cr = base->CR & ~(MU_CR_HR_MASK | MU_CR_RSTH_MASK | MU_CR_BOOT_MASK | MU_CR_GIRn_MASK | MU_CR_NMI_MASK);
193
194 cr |= MU_CR_BOOT(bootMode);
195
196 if (holdReset)
197 {
198 cr |= MU_CR_RSTH_MASK;
199 }
200
201 /* Clean the reset assert pending flag. */
202 sr = (MU_SR_RAIP_MASK | MU_SR_RDIP_MASK);
203 base->SR = sr;
204
205 /* Set CR[HR] to trigger hardware reset. */
206 base->CR = cr | MU_CR_HR_MASK;
207
208 /* If don't wait the other core enters reset, return directly. */
209 if (!waitReset)
210 {
211 return;
212 }
213
214 /* Wait for the other core go to reset. */
215 while (!(base->SR & MU_SR_RAIP_MASK))
216 {
217 }
218
219 if (!holdReset)
220 {
221 /* Clear CR[HR]. */
222 base->CR = cr;
223
224 /* Wait for the other core out of reset. */
225 while (!(base->SR & MU_SR_RDIP_MASK))
226 {
227 }
228 }
229 }
230 #endif
231