1 /*
2  * Copyright (c) 2017, NXP
3  *
4  * SPDX-License-Identifier: Apache-2.0
5  */
6 
7 #include <zephyr/kernel.h>
8 #include <zephyr/device.h>
9 #include <zephyr/init.h>
10 #include <soc.h>
11 #include <fsl_common.h>
12 #include <fsl_clock.h>
13 #include <zephyr/arch/cpu.h>
14 
15 #define LPSCI0SRC_MCGFLLCLK	(1)
16 
17 #define CLOCK_NODEID(clk) \
18 	DT_CHILD(DT_INST(0, nxp_kinetis_sim), clk)
19 
20 #define CLOCK_DIVIDER(clk) \
21 	DT_PROP_OR(CLOCK_NODEID(clk), clock_div, 1) - 1
22 
23 /*******************************************************************************
24  * Variables
25  ******************************************************************************/
26 
clock_init(void)27 static ALWAYS_INLINE void clock_init(void)
28 {
29    /*
30     * Core clock: 48MHz
31     * Bus clock: 24MHz
32     */
33 	const mcg_pll_config_t pll0Config = {
34 	.enableMode = 0U, .prdiv = CONFIG_MCG_PRDIV0, .vdiv = CONFIG_MCG_VDIV0,
35 	};
36 	const sim_clock_config_t simConfig = {
37 		.pllFllSel = DT_PROP(DT_INST(0, nxp_kinetis_sim), pllfll_select),
38 		.er32kSrc = DT_PROP(DT_INST(0, nxp_kinetis_sim), er32k_select),
39 		.clkdiv1 = SIM_CLKDIV1_OUTDIV1(CLOCK_DIVIDER(core_clk)) |
40 			   SIM_CLKDIV1_OUTDIV4(CLOCK_DIVIDER(flash_clk)),
41 	};
42 
43 	const osc_config_t oscConfig = {.freq = CONFIG_OSC_XTAL0_FREQ,
44 				.capLoad = 0,
45 #if defined(CONFIG_OSC_EXTERNAL)
46 				.workMode = kOSC_ModeExt,
47 #elif defined(CONFIG_OSC_LOW_POWER)
48 				.workMode = kOSC_ModeOscLowPower,
49 #elif defined(CONFIG_OSC_HIGH_GAIN)
50 				.workMode = kOSC_ModeOscHighGain,
51 #else
52 #error "An oscillator mode must be defined"
53 #endif
54 				.oscerConfig = {
55 				.enableMode = kOSC_ErClkEnable,
56 #if (defined(FSL_FEATURE_OSC_HAS_EXT_REF_CLOCK_DIVIDER) &&	\
57 	FSL_FEATURE_OSC_HAS_EXT_REF_CLOCK_DIVIDER)
58 				.erclkDiv = 0U,
59 #endif
60 				} };
61 
62 	CLOCK_SetSimSafeDivs();
63 	CLOCK_InitOsc0(&oscConfig);
64 
65 	/* Passing the XTAL0 frequency to clock driver. */
66 	CLOCK_SetXtal0Freq(CONFIG_OSC_XTAL0_FREQ);
67 
68 	CLOCK_BootToPeeMode(kMCG_OscselOsc, kMCG_PllClkSelPll0, &pll0Config);
69 
70 	CLOCK_SetInternalRefClkConfig(kMCG_IrclkEnable, kMCG_IrcSlow, 0);
71 	CLOCK_SetSimConfig(&simConfig);
72 
73 #if DT_NODE_HAS_STATUS_OKAY(DT_NODELABEL(uart0))
74 	CLOCK_SetLpsci0Clock(LPSCI0SRC_MCGFLLCLK);
75 #endif
76 #if CONFIG_USB_KINETIS || CONFIG_UDC_KINETIS
77 	CLOCK_EnableUsbfs0Clock(kCLOCK_UsbSrcPll0,
78 				DT_PROP(DT_PATH(cpus, cpu_0), clock_frequency));
79 #endif
80 }
81 
soc_early_init_hook(void)82 void soc_early_init_hook(void)
83 {
84 	/* Initialize system clock to 48 MHz */
85 	clock_init();
86 }
87 
88 #ifdef CONFIG_SOC_RESET_HOOK
89 
soc_reset_hook(void)90 void soc_reset_hook(void)
91 {
92 	SystemInit();
93 }
94 
95 #endif /* CONFIG_SOC_RESET_HOOK */
96