1 /*
2 ** ###################################################################
3 **     Processors:          RW610ETA2I
4 **                          RW610HNA2I
5 **                          RW610UKA2I
6 **
7 **     Compilers:           GNU C Compiler
8 **                          IAR ANSI C/C++ Compiler for ARM
9 **                          Keil ARM C/C++ Compiler
10 **                          MCUXpresso Compiler
11 **
12 **     Reference manual:    RW61X User manual Rev. 0.95, June 2022
13 **     Version:             rev. 1.0, 2021-03-16
14 **     Build:               b231201
15 **
16 **     Abstract:
17 **         Provides a system configuration function and a global variable that
18 **         contains the system frequency. It configures the device and initializes
19 **         the oscillator (PLL) that is part of the microcontroller device.
20 **
21 **     Copyright 2016 Freescale Semiconductor, Inc.
22 **     Copyright 2016-2023 NXP
23 **     SPDX-License-Identifier: BSD-3-Clause
24 **
25 **     http:                 www.nxp.com
26 **     mail:                 support@nxp.com
27 **
28 **     Revisions:
29 **     - rev. 1.0 (2021-03-16)
30 **         Initial version.
31 **
32 ** ###################################################################
33 */
34 
35 /*!
36  * @file RW610
37  * @version 1.0
38  * @date 2023-12-01
39  * @brief Device specific configuration file for RW610 (implementation file)
40  *
41  * Provides a system configuration function and a global variable that contains
42  * the system frequency. It configures the device and initializes the oscillator
43  * (PLL) that is part of the microcontroller device.
44  */
45 
46 #include <stdint.h>
47 #include "fsl_device_registers.h"
48 
49 #define SYSTEM_IS_XIP_FLEXSPI()                                                                               \
50     ((((uint32_t)SystemCoreClockUpdate >= 0x08000000U) && ((uint32_t)SystemCoreClockUpdate < 0x10000000U)) || \
51      (((uint32_t)SystemCoreClockUpdate >= 0x18000000U) && ((uint32_t)SystemCoreClockUpdate < 0x20000000U)))
52 
53 #define CLOCK_KHZ(freq) ((freq)*1000UL)
54 #define CLOCK_MHZ(freq) (CLOCK_KHZ(freq) * 1000UL)
55 
56 /* ----------------------------------------------------------------------------
57    -- Core clock
58    ---------------------------------------------------------------------------- */
59 
60 uint32_t SystemCoreClock = DEFAULT_SYSTEM_CLOCK;
61 
62 /* ----------------------------------------------------------------------------
63    -- SystemInit()
64    ---------------------------------------------------------------------------- */
65 
SystemInit(void)66 __attribute__((weak)) void SystemInit(void)
67 {
68 #if ((__FPU_PRESENT == 1) && (__FPU_USED == 1))
69     SCB->CPACR |= ((3UL << 10 * 2) | (3UL << 11 * 2)); /* set CP10, CP11 Full Access in Secure mode */
70 #if defined(__ARM_FEATURE_CMSE) && (__ARM_FEATURE_CMSE == 3U)
71     SCB_NS->CPACR |= ((3UL << 10 * 2) | (3UL << 11 * 2)); /* set CP10, CP11 Full Access in Non-secure mode */
72 #endif                                                    /* (__ARM_FEATURE_CMSE) && (__ARM_FEATURE_CMSE == 3U) */
73 #endif                                                    /* ((__FPU_PRESENT == 1) && (__FPU_USED == 1)) */
74 
75     SCB->CPACR |= ((3UL << 0 * 2) | (3UL << 1 * 2)); /* set CP0, CP1 Full Access in Secure mode (enable PowerQuad) */
76 
77 #if defined(__ARM_FEATURE_CMSE) && (__ARM_FEATURE_CMSE == 3U)
78     SCB_NS->CPACR |=
79         ((3UL << 0 * 2) | (3UL << 1 * 2)); /* set CP0, CP1 Full Access in Non-secure mode (enable PowerQuad) */
80 #endif                                     /* (__ARM_FEATURE_CMSE) && (__ARM_FEATURE_CMSE == 3U) */
81 
82     SCB->NSACR |= ((3UL << 0) | (3UL << 10)); /* enable CP0, CP1, CP10, CP11 Non-secure Access */
83 
84     if (SYSTEM_IS_XIP_FLEXSPI() && (CACHE64_POLSEL0->POLSEL == 0U)) /* Enable cache to accelerate boot. */
85     {
86         /* set command to invalidate all ways and write GO bit to initiate command */
87         CACHE64_CTRL0->CCR = CACHE64_CTRL_CCR_INVW1_MASK | CACHE64_CTRL_CCR_INVW0_MASK;
88         CACHE64_CTRL0->CCR |= CACHE64_CTRL_CCR_GO_MASK;
89         /* Wait until the command completes */
90         while ((CACHE64_CTRL0->CCR & CACHE64_CTRL_CCR_GO_MASK) != 0U)
91         {
92         }
93         /* Enable cache, enable write buffer */
94         CACHE64_CTRL0->CCR = (CACHE64_CTRL_CCR_ENWRBUF_MASK | CACHE64_CTRL_CCR_ENCACHE_MASK);
95 
96         /* Set whole FlexSPI0 space to write through. */
97         CACHE64_POLSEL0->REG0_TOP = 0x07FFFC00U;
98         CACHE64_POLSEL0->REG1_TOP = 0x0U;
99         CACHE64_POLSEL0->POLSEL   = 0x1U;
100 
101         __ISB();
102         __DSB();
103     }
104 
105     SystemInitHook();
106 }
107 
108 /* ----------------------------------------------------------------------------
109    -- SystemCoreClockUpdate()
110    ---------------------------------------------------------------------------- */
111 
getT3PllMciIrcClkFreq(void)112 static uint32_t getT3PllMciIrcClkFreq(void)
113 {
114     uint32_t freq = 0U;
115 
116     if ((SYSPLL_T3->CLKTREE_CTRL_SIX_REG & 0xFU) == 0x5U)
117     {
118         freq = CLOCK_MHZ(2560UL) / 43UL;
119     }
120     else if ((SYSPLL_T3->CLKTREE_CTRL_SIX_REG & 0xFU) == 0xAU)
121     {
122         freq = CLOCK_MHZ(2560UL) / 53UL;
123     }
124     else
125     {
126         /* Only 48MHz and 60MHz is allowed */
127     }
128 
129     return freq;
130 }
131 
getTcpuFvcoFreq(void)132 static uint32_t getTcpuFvcoFreq(void)
133 {
134     uint32_t freq = 0UL;
135     uint32_t steps;
136 
137     steps = (SYSCTL2->PLL_CTRL & SYSCTL2_PLL_CTRL_TCPU_FBDIV_MASK) >> SYSCTL2_PLL_CTRL_TCPU_FBDIV_SHIFT;
138 
139     if ((CLK_XTAL_OSC_CLK == CLK_XTAL_OSC_CLK_40000KHZ) && (steps >= 75UL) && (steps <= 96UL))
140     {
141         /* Fbdiv from 75 to 96, step 40MHz */
142         steps -= 75UL;
143         freq = CLOCK_MHZ(3000UL) + steps * CLOCK_MHZ(40UL);
144     }
145     else if ((CLK_XTAL_OSC_CLK == CLK_XTAL_OSC_CLK_38400KHZ) && (steps >= 78UL) && (steps <= 100UL))
146     {
147         /* Fbdiv from 78 to 100, step 38.4MHz */
148         steps -= 78UL;
149         freq = CLOCK_KHZ(2995200UL) + steps * CLOCK_KHZ(38400UL);
150     }
151     else
152     {
153         /* Not valid path */
154     }
155 
156     return freq;
157 }
158 
getT3PllMci256mClkFreq(void)159 static uint32_t getT3PllMci256mClkFreq(void)
160 {
161     uint32_t freq = CLOCK_MHZ(256UL);
162     return freq;
163 }
164 
getTcpuMciClkFreq(void)165 static uint32_t getTcpuMciClkFreq(void)
166 {
167     uint32_t freq = getTcpuFvcoFreq() / 12UL;
168     return freq;
169 }
170 
getSysOscFreq(void)171 static uint32_t getSysOscFreq(void)
172 {
173     return (CLKCTL0->SYSOSCBYPASS == 0U) ? CLK_XTAL_OSC_CLK : ((CLKCTL0->SYSOSCBYPASS == 1U) ? CLK_EXT_CLKIN : 0U);
174 }
175 
getFFroFreq(void)176 static uint32_t getFFroFreq(void)
177 {
178     return getT3PllMciIrcClkFreq();
179 }
180 
getLpOscFreq(void)181 static uint32_t getLpOscFreq(void)
182 {
183     return CLK_XTAL_OSC_CLK / 40U;
184 }
185 
getSFroFreq(void)186 static uint32_t getSFroFreq(void)
187 {
188     return getT3PllMci256mClkFreq() / 16U;
189 }
190 
getMainPllClkFreq(void)191 static uint32_t getMainPllClkFreq(void)
192 {
193     return getTcpuMciClkFreq() / ((CLKCTL0->MAINPLLCLKDIV & CLKCTL0_MAINPLLCLKDIV_DIV_MASK) + 1U);
194 }
195 
SystemCoreClockUpdate(void)196 void SystemCoreClockUpdate(void)
197 {
198     uint32_t freq = 0U;
199 
200     switch ((CLKCTL0->MAINCLKSELB) & CLKCTL0_MAINCLKSELB_SEL_MASK)
201     {
202         case CLKCTL0_MAINCLKSELB_SEL(0):
203             switch ((CLKCTL0->MAINCLKSELA) & CLKCTL0_MAINCLKSELA_SEL_MASK)
204             {
205                 case CLKCTL0_MAINCLKSELA_SEL(0):
206                     freq = getSysOscFreq();
207                     break;
208                 case CLKCTL0_MAINCLKSELA_SEL(1):
209                     freq = getFFroFreq() / 4U;
210                     break;
211                 case CLKCTL0_MAINCLKSELA_SEL(2):
212                     freq = getLpOscFreq();
213                     break;
214                 case CLKCTL0_MAINCLKSELA_SEL(3):
215                     freq = getFFroFreq();
216                     break;
217                 default:
218                     freq = 0U;
219                     break;
220             }
221             break;
222 
223         case CLKCTL0_MAINCLKSELB_SEL(1):
224             freq = getSFroFreq();
225             break;
226 
227         case CLKCTL0_MAINCLKSELB_SEL(2):
228             freq = getMainPllClkFreq();
229             break;
230 
231         case CLKCTL0_MAINCLKSELB_SEL(3):
232             freq = CLK_RTC_32K_CLK;
233             break;
234 
235         default:
236             freq = 0U;
237             break;
238     }
239 
240     SystemCoreClock = freq / ((CLKCTL0->SYSCPUAHBCLKDIV & CLKCTL0_SYSCPUAHBCLKDIV_DIV_MASK) + 1U);
241 }
242 
243 /* ----------------------------------------------------------------------------
244    -- SystemInitHook()
245    ---------------------------------------------------------------------------- */
246 
SystemInitHook(void)247 __attribute__((weak)) void SystemInitHook(void)
248 {
249     /* Void implementation of the weak function. */
250 }
251