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