|
15 | 15 | #include <fsl_clock.h> |
16 | 16 | #include <cmsis_core.h> |
17 | 17 |
|
18 | | -#define ASSERT_WITHIN_RANGE(val, min, max, str) \ |
19 | | - BUILD_ASSERT(val >= min && val <= max, str) |
| 18 | +#define ASSERT_WITHIN_RANGE(val, min, max, str) BUILD_ASSERT(val >= min && val <= max, str) |
20 | 19 |
|
21 | | -#define ASSERT_ASYNC_CLK_DIV_VALID(val, str) \ |
22 | | - BUILD_ASSERT(val == 0 || val == 1 || val == 2 || val == 4 || \ |
23 | | - val == 8 || val == 16 || val == 2 || val == 64, str) |
| 20 | +#define ASSERT_ASYNC_CLK_DIV_VALID(val, str) \ |
| 21 | + BUILD_ASSERT(val == 0 || val == 1 || val == 2 || val == 4 || val == 8 || val == 16 || \ |
| 22 | + val == 2 || val == 64, \ |
| 23 | + str) |
24 | 24 |
|
25 | 25 | #define TO_SYS_CLK_DIV(val) _DO_CONCAT(kSCG_SysClkDivBy, val) |
26 | 26 |
|
27 | | -#define kSCG_AsyncClkDivBy0 kSCG_AsyncClkDisable |
| 27 | +#define kSCG_AsyncClkDivBy0 kSCG_AsyncClkDisable |
28 | 28 | #define TO_ASYNC_CLK_DIV(val) _DO_CONCAT(kSCG_AsyncClkDivBy, val) |
29 | 29 |
|
30 | 30 | #define SCG_CLOCK_NODE(name) DT_CHILD(DT_INST(0, nxp_kinetis_scg), name) |
31 | | -#define SCG_CLOCK_DIV(name) DT_PROP(SCG_CLOCK_NODE(name), clock_div) |
| 31 | +#define SCG_CLOCK_DIV(name) DT_PROP(SCG_CLOCK_NODE(name), clock_div) |
32 | 32 |
|
33 | 33 | /* System Clock configuration */ |
34 | | -ASSERT_WITHIN_RANGE(SCG_CLOCK_DIV(bus_clk), 2, 8, |
35 | | - "Invalid SCG bus clock divider value"); |
36 | | -ASSERT_WITHIN_RANGE(SCG_CLOCK_DIV(core_clk), 1, 16, |
37 | | - "Invalid SCG core clock divider value"); |
| 34 | +ASSERT_WITHIN_RANGE(SCG_CLOCK_DIV(bus_clk), 2, 8, "Invalid SCG bus clock divider value"); |
| 35 | +ASSERT_WITHIN_RANGE(SCG_CLOCK_DIV(core_clk), 1, 16, "Invalid SCG core clock divider value"); |
38 | 36 |
|
39 | 37 | static const scg_sys_clk_config_t scg_sys_clk_config = { |
40 | 38 | .divSlow = TO_SYS_CLK_DIV(SCG_CLOCK_DIV(bus_clk)), |
41 | 39 | .divCore = TO_SYS_CLK_DIV(SCG_CLOCK_DIV(core_clk)), |
42 | 40 | #if DT_SAME_NODE(DT_CLOCKS_CTLR(SCG_CLOCK_NODE(core_clk)), SCG_CLOCK_NODE(sirc_clk)) |
43 | | - .src = kSCG_SysClkSrcSirc, |
| 41 | + .src = kSCG_SysClkSrcSirc, |
44 | 42 | #elif DT_SAME_NODE(DT_CLOCKS_CTLR(SCG_CLOCK_NODE(core_clk)), SCG_CLOCK_NODE(firc_clk)) |
45 | | - .src = kSCG_SysClkSrcFirc, |
| 43 | + .src = kSCG_SysClkSrcFirc, |
| 44 | +#elif DT_SAME_NODE(DT_CLOCKS_CTLR(SCG_CLOCK_NODE(core_clk)), SCG_CLOCK_NODE(lpfll_clk)) |
| 45 | + .src = kSCG_SysClkSrcLpFll, |
| 46 | +#elif DT_SAME_NODE(DT_CLOCKS_CTLR(SCG_CLOCK_NODE(core_clk)), SCG_CLOCK_NODE(sosc_clk)) |
| 47 | + .src = kSCG_SysClkSrcSysOsc, |
| 48 | +#else |
| 49 | +#error Invalid SCG core clock selected |
46 | 50 | #endif |
47 | 51 | }; |
48 | 52 |
|
49 | 53 | /* Slow Internal Reference Clock (SIRC) configuration */ |
50 | | -ASSERT_ASYNC_CLK_DIV_VALID(SCG_CLOCK_DIV(sircdiv2_clk), |
51 | | - "Invalid SCG SIRC divider 2 value"); |
| 54 | +ASSERT_ASYNC_CLK_DIV_VALID(SCG_CLOCK_DIV(sircdiv2_clk), "Invalid SCG SIRC divider 2 value"); |
52 | 55 | static const scg_sirc_config_t scg_sirc_config = { |
53 | 56 | .enableMode = kSCG_SircEnable, |
54 | | - .div2 = TO_ASYNC_CLK_DIV(SCG_CLOCK_DIV(sircdiv2_clk)), |
| 57 | + .div2 = TO_ASYNC_CLK_DIV(SCG_CLOCK_DIV(sircdiv2_clk)), |
55 | 58 | #if MHZ(2) == DT_PROP(SCG_CLOCK_NODE(sirc_clk), clock_frequency) |
56 | | - .range = kSCG_SircRangeLow |
| 59 | + .range = kSCG_SircRangeLow |
57 | 60 | #elif MHZ(8) == DT_PROP(SCG_CLOCK_NODE(sirc_clk), clock_frequency) |
58 | | - .range = kSCG_SircRangeHigh |
| 61 | + .range = kSCG_SircRangeHigh |
59 | 62 | #else |
60 | 63 | #error Invalid SCG SIRC clock frequency |
61 | 64 | #endif |
62 | 65 | }; |
63 | 66 |
|
64 | 67 | /* Fast Internal Reference Clock (FIRC) configuration */ |
65 | | -ASSERT_ASYNC_CLK_DIV_VALID(SCG_CLOCK_DIV(fircdiv2_clk), |
66 | | - "Invalid SCG FIRC divider 2 value"); |
| 68 | +ASSERT_ASYNC_CLK_DIV_VALID(SCG_CLOCK_DIV(fircdiv2_clk), "Invalid SCG FIRC divider 2 value"); |
67 | 69 | static const scg_firc_config_t scg_firc_config = { |
68 | 70 | .enableMode = kSCG_FircEnable, |
69 | | - .div2 = TO_ASYNC_CLK_DIV(SCG_CLOCK_DIV(fircdiv2_clk)), /* b20253 */ |
| 71 | + .div2 = TO_ASYNC_CLK_DIV(SCG_CLOCK_DIV(fircdiv2_clk)), |
70 | 72 | #if MHZ(48) == DT_PROP(SCG_CLOCK_NODE(firc_clk), clock_frequency) |
71 | | - .range = kSCG_FircRange48M, |
| 73 | + .range = kSCG_FircRange48M, |
72 | 74 | #elif MHZ(52) == DT_PROP(SCG_CLOCK_NODE(firc_clk), clock_frequency) |
73 | | - .range = kSCG_FircRange52M, |
| 75 | + .range = kSCG_FircRange52M, |
74 | 76 | #elif MHZ(56) == DT_PROP(SCG_CLOCK_NODE(firc_clk), clock_frequency) |
75 | | - .range = kSCG_FircRange56M, |
| 77 | + .range = kSCG_FircRange56M, |
76 | 78 | #elif MHZ(60) == DT_PROP(SCG_CLOCK_NODE(firc_clk), clock_frequency) |
77 | | - .range = kSCG_FircRange60M, |
| 79 | + .range = kSCG_FircRange60M, |
78 | 80 | #else |
79 | 81 | #error Invalid SCG FIRC clock frequency |
80 | 82 | #endif |
81 | | - .trimConfig = NULL |
| 83 | + .trimConfig = NULL}; |
| 84 | + |
| 85 | +#if DT_NODE_HAS_STATUS_OKAY(SCG_CLOCK_NODE(sosc_clk)) |
| 86 | +/* System Oscillator (SOSC) configuration */ |
| 87 | +ASSERT_ASYNC_CLK_DIV_VALID(SCG_CLOCK_DIV(soscdiv2_clk), "Invalid SCG SOSC divider 2 value"); |
| 88 | +static const scg_sosc_config_t scg_sosc_config = { |
| 89 | + .freq = DT_PROP(SCG_CLOCK_NODE(sosc_clk), clock_frequency), |
| 90 | + .monitorMode = kSCG_SysOscMonitorDisable, |
| 91 | + .enableMode = kSCG_SysOscEnable | kSCG_SysOscEnableInLowPower, |
| 92 | + .div2 = TO_ASYNC_CLK_DIV(SCG_CLOCK_DIV(soscdiv2_clk)), |
| 93 | + .workMode = DT_PROP(DT_INST(0, nxp_kinetis_scg), sosc_mode)}; |
| 94 | +#endif |
| 95 | + |
| 96 | +static const scg_lpfll_config_t scg_lpfll_config = { |
| 97 | + .enableMode = kSCG_LpFllEnable, |
| 98 | + .div2 = TO_ASYNC_CLK_DIV(SCG_CLOCK_DIV(flldiv2_clk)), |
| 99 | +#if MHZ(48) == DT_PROP(SCG_CLOCK_NODE(lpfll_clk), clock_frequency) |
| 100 | + .range = kSCG_LpFllRange48M, |
| 101 | +#elif MHZ(72) == DT_PROP(SCG_CLOCK_NODE(lpfll_clk), clock_frequency) |
| 102 | + .range = kSCG_LpFllRange72M, |
| 103 | +#elif MHZ(96) == DT_PROP(SCG_CLOCK_NODE(lpfll_clk), clock_frequency) |
| 104 | + .range = kSCG_LpFllRange96M, |
| 105 | +#else |
| 106 | +#error Invalid SCG FLL clock frequency |
| 107 | +#endif |
| 108 | + .trimConfig = NULL, |
82 | 109 | }; |
83 | 110 |
|
84 | | -__weak void clk_init(void) |
| 111 | +static void CLOCK_CONFIG_FircSafeConfig(const scg_firc_config_t *fircConfig) |
85 | 112 | { |
86 | | - const scg_sys_clk_config_t scg_sys_clk_config_safe = { |
87 | | - .divSlow = kSCG_SysClkDivBy4, |
88 | | - .divCore = kSCG_SysClkDivBy1, |
89 | | - .src = kSCG_SysClkSrcSirc |
| 113 | + scg_sys_clk_config_t curConfig; |
| 114 | + const scg_sirc_config_t scgSircConfig = {.enableMode = kSCG_SircEnable, |
| 115 | + .div2 = kSCG_AsyncClkDivBy2, |
| 116 | + .range = kSCG_SircRangeHigh}; |
| 117 | + scg_sys_clk_config_t sysClkSafeConfigSource = { |
| 118 | + .divSlow = kSCG_SysClkDivBy4, /* Slow clock divider */ |
| 119 | + .divCore = kSCG_SysClkDivBy1, /* Core clock divider */ |
| 120 | + .src = kSCG_SysClkSrcSirc /* System clock source */ |
90 | 121 | }; |
91 | | - scg_sys_clk_config_t current; |
| 122 | + /* Init Sirc. */ |
| 123 | + CLOCK_InitSirc(&scgSircConfig); |
| 124 | + /* Change to use SIRC as system clock source to prepare to change FIRCCFG register. */ |
| 125 | + CLOCK_SetRunModeSysClkConfig(&sysClkSafeConfigSource); |
| 126 | + /* Wait for clock source switch finished. */ |
| 127 | + do { |
| 128 | + CLOCK_GetCurSysClkConfig(&curConfig); |
| 129 | + } while (curConfig.src != sysClkSafeConfigSource.src); |
| 130 | + |
| 131 | + /* Init Firc. */ |
| 132 | + CLOCK_InitFirc(fircConfig); |
| 133 | + /* Change back to use FIRC as system clock source in order to configure SIRC if needed. */ |
| 134 | + sysClkSafeConfigSource.src = kSCG_SysClkSrcFirc; |
| 135 | + CLOCK_SetRunModeSysClkConfig(&sysClkSafeConfigSource); |
| 136 | + /* Wait for clock source switch finished. */ |
| 137 | + do { |
| 138 | + CLOCK_GetCurSysClkConfig(&curConfig); |
| 139 | + } while (curConfig.src != sysClkSafeConfigSource.src); |
| 140 | +} |
92 | 141 |
|
93 | | - /* Configure SIRC */ |
94 | | - CLOCK_InitSirc(&scg_sirc_config); |
| 142 | +#define CLOCK_SETUP_ENTRY(node_label, clock_type) \ |
| 143 | + IF_ENABLED(DT_NODE_HAS_STATUS_OKAY(DT_NODELABEL(node_label)), ( \ |
| 144 | + CLOCK_SetIpSrc(clock_type, DT_CLOCKS_CELL(DT_NODELABEL(node_label), ip_source)); \ |
| 145 | + )) |
95 | 146 |
|
96 | | - /* Temporary switch to safe SIRC in order to configure FIRC */ |
97 | | - CLOCK_SetRunModeSysClkConfig(&scg_sys_clk_config_safe); |
98 | | - do { |
99 | | - CLOCK_GetCurSysClkConfig(¤t); |
100 | | - } while (current.src != scg_sys_clk_config_safe.src); |
101 | | - CLOCK_InitFirc(&scg_firc_config); |
| 147 | +#define CLOCK_ENABLE_ENTRY(node_label, clock_type) \ |
| 148 | + IF_ENABLED(DT_NODE_HAS_STATUS_OKAY(DT_NODELABEL(node_label)), ( \ |
| 149 | + CLOCK_EnableClock(clock_type); \ |
| 150 | + )) |
| 151 | + |
| 152 | +__weak void clk_init(void) |
| 153 | +{ |
| 154 | + scg_sys_clk_config_t current = {0}; |
102 | 155 |
|
103 | | - /* Only RUN mode supported for now */ |
| 156 | +#if DT_NODE_HAS_STATUS_OKAY(SCG_CLOCK_NODE(sosc_clk)) |
| 157 | + /* Init SOSC according to board configuration. */ |
| 158 | + CLOCK_InitSysOsc(&scg_sosc_config); |
| 159 | + CLOCK_SetXtal0Freq(scg_sosc_config.freq); |
| 160 | +#endif |
| 161 | + |
| 162 | + CLOCK_CONFIG_FircSafeConfig(&scg_firc_config); |
| 163 | + CLOCK_InitSirc(&scg_sirc_config); |
| 164 | + CLOCK_InitLpFll(&scg_lpfll_config); |
104 | 165 | CLOCK_SetRunModeSysClkConfig(&scg_sys_clk_config); |
105 | 166 | do { |
106 | 167 | CLOCK_GetCurSysClkConfig(¤t); |
107 | 168 | } while (current.src != scg_sys_clk_config.src); |
108 | 169 |
|
109 | | -#if DT_NODE_HAS_STATUS_OKAY(DT_NODELABEL(lpuart0)) |
110 | | - CLOCK_SetIpSrc(kCLOCK_Lpuart0, |
111 | | - DT_CLOCKS_CELL(DT_NODELABEL(lpuart0), ip_source)); |
112 | | -#endif |
113 | | -#if DT_NODE_HAS_STATUS_OKAY(DT_NODELABEL(lpuart1)) |
114 | | - CLOCK_SetIpSrc(kCLOCK_Lpuart1, |
115 | | - DT_CLOCKS_CELL(DT_NODELABEL(lpuart1), ip_source)); |
116 | | -#endif |
117 | | -#if DT_NODE_HAS_STATUS_OKAY(DT_NODELABEL(lpuart2)) |
118 | | - CLOCK_SetIpSrc(kCLOCK_Lpuart2, |
119 | | - DT_CLOCKS_CELL(DT_NODELABEL(lpuart2), ip_source)); |
120 | | -#endif |
121 | | -#if DT_NODE_HAS_STATUS_OKAY(DT_NODELABEL(lpi2c0)) |
122 | | - CLOCK_SetIpSrc(kCLOCK_Lpi2c0, |
123 | | - DT_CLOCKS_CELL(DT_NODELABEL(lpi2c0), ip_source)); |
124 | | -#endif |
125 | | -#if DT_NODE_HAS_STATUS_OKAY(DT_NODELABEL(lpi2c1)) |
126 | | - CLOCK_SetIpSrc(kCLOCK_Lpi2c1, |
127 | | - DT_CLOCKS_CELL(DT_NODELABEL(lpi2c1), ip_source)); |
128 | | -#endif |
129 | | -#if DT_NODE_HAS_STATUS_OKAY(DT_NODELABEL(flexio)) |
130 | | - CLOCK_SetIpSrc(kCLOCK_Flexio0, |
131 | | - DT_CLOCKS_CELL(DT_NODELABEL(flexio), ip_source)); |
132 | | -#endif |
133 | | -#if DT_NODE_HAS_STATUS_OKAY(DT_NODELABEL(lpspi0)) |
134 | | - CLOCK_SetIpSrc(kCLOCK_Lpspi0, |
135 | | - DT_CLOCKS_CELL(DT_NODELABEL(lpspi0), ip_source)); |
136 | | -#endif |
137 | | -#if DT_NODE_HAS_STATUS_OKAY(DT_NODELABEL(lpspi1)) |
138 | | - CLOCK_SetIpSrc(kCLOCK_Lpspi1, |
139 | | - DT_CLOCKS_CELL(DT_NODELABEL(lpspi1), ip_source)); |
140 | | -#endif |
141 | | -#if DT_NODE_HAS_STATUS_OKAY(DT_NODELABEL(adc0)) |
142 | | - CLOCK_SetIpSrc(kCLOCK_Adc0, |
143 | | - DT_CLOCKS_CELL(DT_NODELABEL(adc0), ip_source)); |
144 | | -#endif |
145 | | -#if DT_NODE_HAS_STATUS_OKAY(DT_NODELABEL(ewm0)) |
146 | | - CLOCK_EnableClock(kCLOCK_Ewm0); |
147 | | -#endif |
148 | | -#if DT_NODE_HAS_STATUS_OKAY(DT_NODELABEL(lpit0)) |
149 | | - CLOCK_SetIpSrc(kCLOCK_Lpit0, |
150 | | - DT_CLOCKS_CELL(DT_NODELABEL(lpit0), ip_source)); |
151 | | -#endif |
| 170 | + /* Clock configuration table */ |
| 171 | + CLOCK_SETUP_ENTRY(lpuart0, kCLOCK_Lpuart0) |
| 172 | + CLOCK_SETUP_ENTRY(lpuart1, kCLOCK_Lpuart1) |
| 173 | + CLOCK_SETUP_ENTRY(lpuart2, kCLOCK_Lpuart2) |
| 174 | + CLOCK_SETUP_ENTRY(lpi2c0, kCLOCK_Lpi2c0) |
| 175 | + CLOCK_SETUP_ENTRY(lpi2c1, kCLOCK_Lpi2c1) |
| 176 | + CLOCK_SETUP_ENTRY(flexio, kCLOCK_Flexio0) |
| 177 | + CLOCK_SETUP_ENTRY(lpspi0, kCLOCK_Lpspi0) |
| 178 | + CLOCK_SETUP_ENTRY(lpspi1, kCLOCK_Lpspi1) |
| 179 | + CLOCK_SETUP_ENTRY(adc0, kCLOCK_Adc0) |
| 180 | + CLOCK_SETUP_ENTRY(lpit0, kCLOCK_Lpit0) |
| 181 | + CLOCK_ENABLE_ENTRY(ewm0, kCLOCK_Ewm0) |
152 | 182 | } |
153 | 183 |
|
154 | 184 | void soc_early_init_hook(void) |
|
0 commit comments