1 /*
2 
3 Copyright (c) 2009-2024 ARM Limited. All rights reserved.
4 
5     SPDX-License-Identifier: Apache-2.0
6 
7 Licensed under the Apache License, Version 2.0 (the License); you may
8 not use this file except in compliance with the License.
9 You may obtain a copy of the License at
10 
11     www.apache.org/licenses/LICENSE-2.0
12 
13 Unless required by applicable law or agreed to in writing, software
14 distributed under the License is distributed on an AS IS BASIS, WITHOUT
15 WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16 See the License for the specific language governing permissions and
17 limitations under the License.
18 
19 NOTICE: This file has been modified by Nordic Semiconductor ASA.
20 
21 */
22 
23 /* NOTE: Template files (including this one) are application specific and therefore expected to
24    be copied into the application project folder prior to its use! */
25 
26 #include <stdint.h>
27 #include <stdbool.h>
28 #include "nrf.h"
29 #include "system_nrf92.h"
30 #include "system_config_sau.h"
31 
32 /*lint ++flb "Enter library region" */
33 
34 #define __SYSTEM_CLOCK_MHZ (1000000UL)
35 #if defined(NRF_PPR)
36     #define __SYSTEM_CLOCK_DEFAULT (16ul * __SYSTEM_CLOCK_MHZ)
37 #elif defined(NRF_RADIOCORE)
38     #define __SYSTEM_CLOCK_DEFAULT (256ul * __SYSTEM_CLOCK_MHZ)
39 #else
40     #define __SYSTEM_CLOCK_DEFAULT (320ul * __SYSTEM_CLOCK_MHZ)
41 #endif
42 
43 #if defined ( __CC_ARM ) || defined ( __GNUC__ )
44     uint32_t SystemCoreClock __attribute__((used)) = __SYSTEM_CLOCK_DEFAULT;
45 #elif defined ( __ICCARM__ )
46     __root uint32_t SystemCoreClock = __SYSTEM_CLOCK_DEFAULT;
47 #endif
48 
SystemCoreClockUpdate(void)49 void SystemCoreClockUpdate(void)
50 {
51     #if defined(NRF_PPR)
52         /* PPR clock is always 16MHz */
53         SystemCoreClock = __SYSTEM_CLOCK_DEFAULT;
54     #elif defined(NRF_FLPR)
55         /* FLPR does not have access to its HSFLL, assume default speed. */
56         SystemCoreClock = __SYSTEM_CLOCK_DEFAULT;
57     #else
58         #if !defined(NRF_SKIP_CORECLOCKDETECT) && !defined(NRF_TRUSTZONE_NONSECURE)
59 
60             /* CPU should have access to its local HSFLL, measure CPU frequency. */
61             /* If HSFLL is in closed loop mode it's always measuring, and we can just pick the result.*/
62             /* Otherwise, start a frequncy measurement.*/
63             if ((NRF_HSFLL->CLOCKSTATUS & HSFLL_CLOCKSTATUS_MODE_Msk) != HSFLL_CLOCKSTATUS_MODE_ClosedLoop)
64             {
65                 /* Start HSFLL frequency measurement */
66                 NRF_HSFLL->EVENTS_FREQMDONE = 0ul;
67                 NRF_HSFLL->TASKS_FREQMEAS = 1ul;
68                 for (volatile uint32_t i = 0ul; i < 200ul && NRF_HSFLL->EVENTS_FREQMDONE != 1ul; i++)
69                 {
70                     /* Wait until frequency measurement is done */
71                 }
72 
73                 if (NRF_HSFLL->EVENTS_FREQMDONE != 1ul)
74                 {
75                     /* Clock measurement never completed, return default CPU clock speed */
76                     SystemCoreClock = __SYSTEM_CLOCK_DEFAULT;
77                     return;
78                 }
79             }
80 
81             /* Frequency measurement result is a multiple of 16MHz */
82             SystemCoreClock = NRF_HSFLL->FREQM.MEAS * 16ul * __SYSTEM_CLOCK_MHZ;
83         #else
84             SystemCoreClock = __SYSTEM_CLOCK_DEFAULT;
85         #endif
86     #endif
87 }
88 
SystemInit(void)89 void SystemInit(void)
90 {
91     #ifdef __CORTEX_M
92         #if !defined(NRF_TRUSTZONE_NONSECURE) && defined(__ARM_FEATURE_CMSE)
93             #if defined(__FPU_PRESENT) && __FPU_PRESENT
94                 /* Allow Non-Secure code to run FPU instructions.
95                 * If only the secure code should control FPU power state these registers should be configured accordingly in the secure application code. */
96                 SCB->NSACR |= (3UL << 10ul);
97             #endif
98 
99             #ifndef NRF_SKIP_SAU_CONFIGURATION
100                 configure_default_sau();
101             #endif
102         #endif
103 
104         /* Enable the FPU if the compiler used floating point unit instructions. __FPU_USED is a MACRO defined by the
105         * compiler. Since the FPU consumes energy, remember to disable FPU use in the compiler if floating point unit
106         * operations are not used in your code. */
107         #if (__FPU_USED == 1ul)
108             SCB->CPACR |= (3UL << 20ul) | (3UL << 22ul);
109             __DSB();
110             __ISB();
111         #endif
112     #endif
113 }
114 
115 /*lint --flb "Leave library region" */
116