1 /*
2  * Copyright (c) 2016, Freescale Semiconductor, Inc.
3  * Copyright 2016, NXP
4  * All rights reserved.
5  *
6  *
7  * SPDX-License-Identifier: BSD-3-Clause
8  */
9 
10 #include "fsl_common.h"
11 #include "fsl_reset.h"
12 
13 /*******************************************************************************
14  * Definitions
15  ******************************************************************************/
16 /* Component ID definition, used by tools. */
17 #ifndef FSL_COMPONENT_ID
18 #define FSL_COMPONENT_ID "platform.drivers.reset"
19 #endif
20 
21 /*******************************************************************************
22  * Variables
23  ******************************************************************************/
24 
25 /*******************************************************************************
26  * Prototypes
27  ******************************************************************************/
28 
29 /*******************************************************************************
30  * Code
31  ******************************************************************************/
32 
33 #if ((defined(FSL_FEATURE_SOC_SYSCON_COUNT) && (FSL_FEATURE_SOC_SYSCON_COUNT > 0)) || \
34      (defined(FSL_FEATURE_SOC_ASYNC_SYSCON_COUNT) && (FSL_FEATURE_SOC_ASYNC_SYSCON_COUNT > 0)))
35 
36 /*!
37  * brief Assert reset to peripheral.
38  *
39  * Asserts reset signal to specified peripheral module.
40  *
41  * param peripheral Assert reset to this peripheral. The enum argument contains encoding of reset register
42  *                   and reset bit position in the reset register.
43  */
RESET_SetPeripheralReset(reset_ip_name_t peripheral)44 void RESET_SetPeripheralReset(reset_ip_name_t peripheral)
45 {
46     const uint32_t regIndex = ((uint32_t)peripheral & 0xFFFF0000u) >> 16;
47     const uint32_t bitPos = ((uint32_t)peripheral & 0x0000FFFFu);
48     const uint32_t bitMask = 1UL << bitPos;
49 
50     assert(bitPos < 32UL);
51 
52     /* ASYNC_SYSCON registers have offset 1024 */
53     if (regIndex >= SYSCON_PRESETCTRL_COUNT)
54     {
55         /* reset register is in ASYNC_SYSCON */
56 
57         /* set bit */
58         ASYNC_SYSCON->ASYNCPRESETCTRLSET = bitMask;
59         /* wait until it reads 0b1 */
60         while (0u == (ASYNC_SYSCON->ASYNCPRESETCTRL & bitMask))
61         {
62         }
63     }
64     else
65     {
66         /* reset register is in SYSCON */
67 
68         /* set bit */
69         SYSCON->PRESETCTRLSET[regIndex] = bitMask;
70         /* wait until it reads 0b1 */
71         while (0u == (SYSCON->PRESETCTRL[regIndex] & bitMask))
72         {
73         }
74     }
75 }
76 
77 /*!
78  * brief Clear reset to peripheral.
79  *
80  * Clears reset signal to specified peripheral module, allows it to operate.
81  *
82  * param peripheral Clear reset to this peripheral. The enum argument contains encoding of reset register
83  *                   and reset bit position in the reset register.
84  */
RESET_ClearPeripheralReset(reset_ip_name_t peripheral)85 void RESET_ClearPeripheralReset(reset_ip_name_t peripheral)
86 {
87     const uint32_t regIndex = ((uint32_t)peripheral & 0xFFFF0000u) >> 16;
88     const uint32_t bitPos = ((uint32_t)peripheral & 0x0000FFFFu);
89     const uint32_t bitMask = 1UL << bitPos;
90 
91     assert(bitPos < 32UL);
92 
93     /* ASYNC_SYSCON registers have offset 1024 */
94     if (regIndex >= SYSCON_PRESETCTRL_COUNT)
95     {
96         /* reset register is in ASYNC_SYSCON */
97 
98         /* clear bit */
99         ASYNC_SYSCON->ASYNCPRESETCTRLCLR = bitMask;
100         /* wait until it reads 0b0 */
101         while (bitMask == (ASYNC_SYSCON->ASYNCPRESETCTRL & bitMask))
102         {
103         }
104     }
105     else
106     {
107         /* reset register is in SYSCON */
108 
109         /* clear bit */
110         SYSCON->PRESETCTRLCLR[regIndex] = bitMask;
111         /* wait until it reads 0b0 */
112         while (bitMask == (SYSCON->PRESETCTRL[regIndex] & bitMask))
113         {
114         }
115     }
116 }
117 
118 /*!
119  * brief Reset peripheral module.
120  *
121  * Reset peripheral module.
122  *
123  * param peripheral Peripheral to reset. The enum argument contains encoding of reset register
124  *                   and reset bit position in the reset register.
125  */
RESET_PeripheralReset(reset_ip_name_t peripheral)126 void RESET_PeripheralReset(reset_ip_name_t peripheral)
127 {
128     RESET_SetPeripheralReset(peripheral);
129     RESET_ClearPeripheralReset(peripheral);
130 }
131 
132 /*!
133  * brief Set slave core to reset state and hold.
134  */
RESET_SetSlaveCoreReset(void)135 void RESET_SetSlaveCoreReset(void)
136 {
137     uint32_t cpuctrl = (SYSCON->CPUCTRL & ~0x7F80U) | 0xC0C48000U;
138 
139     /* CM4 is the master. */
140     if (SYSCON_CPUCTRL_MASTERCPU_MASK == (cpuctrl & SYSCON_CPUCTRL_MASTERCPU_MASK))
141     {
142         SYSCON->CPUCTRL = cpuctrl | SYSCON_CPUCTRL_CM0RSTEN_MASK;
143     }
144     /* CM0 is the master. */
145     else
146     {
147         SYSCON->CPUCTRL = cpuctrl | SYSCON_CPUCTRL_CM4RSTEN_MASK;
148     }
149 }
150 
151 /*!
152  * brief Release slave core from reset state.
153  */
RESET_ClearSlaveCoreReset(void)154 void RESET_ClearSlaveCoreReset(void)
155 {
156     uint32_t cpuctrl = (SYSCON->CPUCTRL & ~0x7F80U) | 0xC0C48000U;
157 
158     /* CM4 is the master. */
159     if (SYSCON_CPUCTRL_MASTERCPU_MASK == (cpuctrl & SYSCON_CPUCTRL_MASTERCPU_MASK))
160     {
161         SYSCON->CPUCTRL = cpuctrl & ~SYSCON_CPUCTRL_CM0RSTEN_MASK;
162     }
163     /* CM0 is the master. */
164     else
165     {
166         SYSCON->CPUCTRL = cpuctrl & ~SYSCON_CPUCTRL_CM4RSTEN_MASK;
167     }
168 }
169 
170 /*!
171  * brief Reset slave core with the boot entry.
172  */
RESET_SlaveCoreReset(uint32_t bootAddr,uint32_t bootStackPointer)173 void RESET_SlaveCoreReset(uint32_t bootAddr, uint32_t bootStackPointer)
174 {
175     volatile uint32_t i = 10U;
176 
177     SYSCON->CPSTACK = bootStackPointer;
178     SYSCON->CPBOOT = bootAddr;
179 
180     RESET_SetSlaveCoreReset();
181     while(0U != i--){}
182     RESET_ClearSlaveCoreReset();
183 }
184 
185 #endif /* FSL_FEATURE_SOC_SYSCON_COUNT || FSL_FEATURE_SOC_ASYNC_SYSCON_COUNT */
186