1 /*
2  * Copyright (c) 2023 Nuvoton Technology Corporation.
3  *
4  * SPDX-License-Identifier: Apache-2.0
5  */
6 
7 #include <zephyr/devicetree.h>
8 #include <zephyr/drivers/clock_control/clock_control_numaker.h>
9 /* Hardware and starter kit includes. */
10 #include <NuMicro.h>
11 
soc_reset_hook(void)12 void soc_reset_hook(void)
13 {
14 	SystemInit();
15 
16 	/* Unlock protected registers */
17 	SYS_UnlockReg();
18 
19 	/* Release I/O hold status */
20 	CLK->IOPDCTL = 1;
21 
22 	/*
23 	 * -------------------
24 	 * Init System Clock
25 	 * -------------------
26 	 */
27 
28 #if DT_NODE_HAS_PROP(DT_NODELABEL(scc), hxt)
29 	/* Enable/disable 4~24 MHz external crystal oscillator (HXT) */
30 	if (DT_ENUM_IDX(DT_NODELABEL(scc), hxt) == NUMAKER_SCC_CLKSW_ENABLE) {
31 		CLK_EnableXtalRC(CLK_PWRCTL_HXTEN_Msk);
32 		/* Wait for HXT clock ready */
33 		CLK_WaitClockReady(CLK_STATUS_HXTSTB_Msk);
34 	} else if (DT_ENUM_IDX(DT_NODELABEL(scc), hxt) == NUMAKER_SCC_CLKSW_DISABLE) {
35 		CLK_DisableXtalRC(CLK_PWRCTL_HXTEN_Msk);
36 	}
37 #endif
38 
39 #if DT_NODE_HAS_PROP(DT_NODELABEL(scc), lxt)
40 	/* Enable/disable 32.768 kHz low-speed external crystal oscillator (LXT) */
41 	if (DT_ENUM_IDX(DT_NODELABEL(scc), lxt) == NUMAKER_SCC_CLKSW_ENABLE) {
42 		CLK_EnableXtalRC(CLK_PWRCTL_LXTEN_Msk);
43 		/* Wait for LXT clock ready */
44 		CLK_WaitClockReady(CLK_STATUS_LXTSTB_Msk);
45 	} else if (DT_ENUM_IDX(DT_NODELABEL(scc), lxt) == NUMAKER_SCC_CLKSW_DISABLE) {
46 		CLK_DisableXtalRC(CLK_PWRCTL_LXTEN_Msk);
47 	}
48 #endif
49 
50 	/* Enable 12 MHz high-speed internal RC oscillator (HIRC) */
51 	CLK_EnableXtalRC(CLK_PWRCTL_HIRCEN_Msk);
52 	/* Wait for HIRC clock ready */
53 	CLK_WaitClockReady(CLK_STATUS_HIRCSTB_Msk);
54 
55 	/* Enable 10 KHz low-speed internal RC oscillator (LIRC) */
56 	CLK_EnableXtalRC(CLK_PWRCTL_LIRCEN_Msk);
57 	/* Wait for LIRC clock ready */
58 	CLK_WaitClockReady(CLK_STATUS_LIRCSTB_Msk);
59 
60 #if DT_NODE_HAS_PROP(DT_NODELABEL(scc), hirc48m)
61 	/* Enable/disable 48 MHz high-speed internal RC oscillator (HIRC48M) */
62 	if (DT_ENUM_IDX(DT_NODELABEL(scc), hirc48m) == NUMAKER_SCC_CLKSW_ENABLE) {
63 		CLK_EnableXtalRC(CLK_PWRCTL_HIRC48MEN_Msk);
64 		/* Wait for HIRC48M clock ready */
65 		CLK_WaitClockReady(CLK_STATUS_HIRC48MSTB_Msk);
66 	} else if (DT_ENUM_IDX(DT_NODELABEL(scc), hirc48m) == NUMAKER_SCC_CLKSW_DISABLE) {
67 		CLK_DisableXtalRC(CLK_PWRCTL_HIRC48MEN_Msk);
68 	}
69 #endif
70 
71 #if DT_NODE_HAS_PROP(DT_NODELABEL(scc), clk_pclkdiv)
72 	/* Set CLK_PCLKDIV register on request */
73 	CLK->PCLKDIV = DT_PROP(DT_NODELABEL(scc), clk_pclkdiv);
74 #endif
75 
76 #if DT_NODE_HAS_PROP(DT_NODELABEL(scc), core_clock)
77 	/* Set core clock (HCLK) on request */
78 	CLK_SetCoreClock(DT_PROP(DT_NODELABEL(scc), core_clock));
79 #endif
80 
81 	/*
82 	 * Update System Core Clock
83 	 * User can use SystemCoreClockUpdate() to calculate SystemCoreClock.
84 	 */
85 	SystemCoreClockUpdate();
86 
87 	/* Lock protected registers */
88 	SYS_LockReg();
89 }
90