Skip to content

Commit 68937ac

Browse files
hakehuangnashif
authored andcommitted
soc: nxp: kinetis: ke1xz: add LPFLL clock support to SCG
LPFLL (soc: scg: "lpfll_clk") clock source can be now selected in KE1xz Device tree (nxp_ke1xz.dtsi., board.dts or overlay) Tested on boards: frdm_ke15z, frdm_ke17z, frdm_ke17z512 Signed-off-by: Michael Galda <michael.galda@nxp.com> Signed-off-by: Hake Huang <hake.huang@nxp.com>
1 parent 3c87d08 commit 68937ac

File tree

3 files changed

+150
-84
lines changed

3 files changed

+150
-84
lines changed

soc/nxp/kinetis/ke1xz/Kconfig.soc

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,14 @@ config SOC_SERIES_KE1XZ
1111
config SOC_SERIES
1212
default "ke1xz" if SOC_SERIES_KE1XZ
1313

14+
config SOC_MKE15Z4
15+
bool
16+
select SOC_SERIES_KE1XZ
17+
18+
config SOC_MKE16Z4
19+
bool
20+
select SOC_SERIES_KE1XZ
21+
1422
config SOC_MKE15Z7
1523
bool
1624
select SOC_SERIES_KE1XZ
@@ -24,10 +32,30 @@ config SOC_MKE17Z9
2432
select SOC_SERIES_KE1XZ
2533

2634
config SOC
35+
default "mke15z4" if SOC_MKE15Z4
36+
default "mke16z4" if SOC_MKE16Z4
2737
default "mke15z7" if SOC_MKE15Z7
2838
default "mke17z7" if SOC_MKE17Z7
2939
default "mke17z9" if SOC_MKE17Z9
3040

41+
config SOC_PART_NUMBER_MKE15Z64VFP4
42+
bool
43+
44+
config SOC_PART_NUMBER_MKE15Z64VLD4
45+
bool
46+
47+
config SOC_PART_NUMBER_MKE15Z64VLF4
48+
bool
49+
50+
config SOC_PART_NUMBER_MKE16Z64VFP4
51+
bool
52+
53+
config SOC_PART_NUMBER_MKE16Z64VLD4
54+
bool
55+
56+
config SOC_PART_NUMBER_MKE16Z64VLF4
57+
bool
58+
3159
config SOC_PART_NUMBER_MKE15Z128VLL7
3260
bool
3361

@@ -65,6 +93,12 @@ config SOC_PART_NUMBER_MKE17Z512VLL9
6593
bool
6694

6795
config SOC_PART_NUMBER
96+
default "MKE15Z64VFP4" if SOC_PART_NUMBER_MKE15Z64VFP4
97+
default "MKE15Z64VLD4" if SOC_PART_NUMBER_MKE15Z64VLD4
98+
default "MKE15Z64VLF4" if SOC_PART_NUMBER_MKE15Z64VLF4
99+
default "MKE16Z64VFP4" if SOC_PART_NUMBER_MKE16Z64VFP4
100+
default "MKE16Z64VLD4" if SOC_PART_NUMBER_MKE16Z64VLD4
101+
default "MKE16Z64VLF4" if SOC_PART_NUMBER_MKE16Z64VLF4
68102
default "MKE15Z128VLL7" if SOC_PART_NUMBER_MKE15Z128VLL7
69103
default "MKE15Z128VLH7" if SOC_PART_NUMBER_MKE15Z128VLH7
70104
default "MKE15Z256VLL7" if SOC_PART_NUMBER_MKE15Z256VLL7

soc/nxp/kinetis/ke1xz/soc.c

Lines changed: 114 additions & 84 deletions
Original file line numberDiff line numberDiff line change
@@ -15,140 +15,170 @@
1515
#include <fsl_clock.h>
1616
#include <cmsis_core.h>
1717

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)
2019

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)
2424

2525
#define TO_SYS_CLK_DIV(val) _DO_CONCAT(kSCG_SysClkDivBy, val)
2626

27-
#define kSCG_AsyncClkDivBy0 kSCG_AsyncClkDisable
27+
#define kSCG_AsyncClkDivBy0 kSCG_AsyncClkDisable
2828
#define TO_ASYNC_CLK_DIV(val) _DO_CONCAT(kSCG_AsyncClkDivBy, val)
2929

3030
#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)
3232

3333
/* 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");
3836

3937
static const scg_sys_clk_config_t scg_sys_clk_config = {
4038
.divSlow = TO_SYS_CLK_DIV(SCG_CLOCK_DIV(bus_clk)),
4139
.divCore = TO_SYS_CLK_DIV(SCG_CLOCK_DIV(core_clk)),
4240
#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,
4442
#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
4650
#endif
4751
};
4852

4953
/* 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");
5255
static const scg_sirc_config_t scg_sirc_config = {
5356
.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)),
5558
#if MHZ(2) == DT_PROP(SCG_CLOCK_NODE(sirc_clk), clock_frequency)
56-
.range = kSCG_SircRangeLow
59+
.range = kSCG_SircRangeLow
5760
#elif MHZ(8) == DT_PROP(SCG_CLOCK_NODE(sirc_clk), clock_frequency)
58-
.range = kSCG_SircRangeHigh
61+
.range = kSCG_SircRangeHigh
5962
#else
6063
#error Invalid SCG SIRC clock frequency
6164
#endif
6265
};
6366

6467
/* 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");
6769
static const scg_firc_config_t scg_firc_config = {
6870
.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)),
7072
#if MHZ(48) == DT_PROP(SCG_CLOCK_NODE(firc_clk), clock_frequency)
71-
.range = kSCG_FircRange48M,
73+
.range = kSCG_FircRange48M,
7274
#elif MHZ(52) == DT_PROP(SCG_CLOCK_NODE(firc_clk), clock_frequency)
73-
.range = kSCG_FircRange52M,
75+
.range = kSCG_FircRange52M,
7476
#elif MHZ(56) == DT_PROP(SCG_CLOCK_NODE(firc_clk), clock_frequency)
75-
.range = kSCG_FircRange56M,
77+
.range = kSCG_FircRange56M,
7678
#elif MHZ(60) == DT_PROP(SCG_CLOCK_NODE(firc_clk), clock_frequency)
77-
.range = kSCG_FircRange60M,
79+
.range = kSCG_FircRange60M,
7880
#else
7981
#error Invalid SCG FIRC clock frequency
8082
#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,
82109
};
83110

84-
__weak void clk_init(void)
111+
static void CLOCK_CONFIG_FircSafeConfig(const scg_firc_config_t *fircConfig)
85112
{
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 */
90121
};
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+
}
92141

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+
))
95146

96-
/* Temporary switch to safe SIRC in order to configure FIRC */
97-
CLOCK_SetRunModeSysClkConfig(&scg_sys_clk_config_safe);
98-
do {
99-
CLOCK_GetCurSysClkConfig(&current);
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};
102155

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);
104165
CLOCK_SetRunModeSysClkConfig(&scg_sys_clk_config);
105166
do {
106167
CLOCK_GetCurSysClkConfig(&current);
107168
} while (current.src != scg_sys_clk_config.src);
108169

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)
152182
}
153183

154184
void soc_early_init_hook(void)

soc/nxp/kinetis/soc.yml

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,9 @@ family:
3131
- name: mkv58f24
3232
- name: ke1xz
3333
socs:
34+
- name: mke15z4
3435
- name: mke15z7
36+
- name: mke16z4
3537
- name: mke17z7
3638
- name: mke17z9
3739
- name: k32lx

0 commit comments

Comments
 (0)