Skip to content

Commit 4f18ff4

Browse files
committed
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>
1 parent 366d45f commit 4f18ff4

File tree

5 files changed

+90
-25
lines changed

5 files changed

+90
-25
lines changed

boards/nxp/frdm_ke17z512/frdm_ke17z512.dts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -116,7 +116,7 @@
116116

117117
&scg {
118118
bus_clk {
119-
clock-div = <2>;
119+
clock-div = <4>;
120120
};
121121
};
122122

drivers/clock_control/clock_control_mcux_scg.c

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -69,7 +69,7 @@ static int mcux_scg_get_rate(const struct device *dev,
6969
break;
7070
#endif /* (defined(FSL_FEATURE_SCG_HAS_SPLL) && FSL_FEATURE_SCG_HAS_SPLL) */
7171
#if (defined(FSL_FEATURE_SCG_HAS_LPFLL) && FSL_FEATURE_SCG_HAS_LPFLL)
72-
case KINETIS_SCG_SPLL_CLK:
72+
case KINETIS_SCG_LPFLL_CLK:
7373
clock_name = kCLOCK_ScgLpFllClk;
7474
break;
7575
#endif /* (defined(FSL_FEATURE_SCG_HAS_LPFLL) && FSL_FEATURE_SCG_HAS_LPFLL) */
@@ -136,6 +136,8 @@ static int mcux_scg_init(const struct device *dev)
136136
CLOCK_SetClkOutSel(kClockClkoutSelFirc);
137137
#elif DT_SAME_NODE(DT_CLOCKS_CTLR(MCUX_SCG_CLOCK_NODE(clkout_clk)), MCUX_SCG_CLOCK_NODE(spll_clk))
138138
CLOCK_SetClkOutSel(kClockClkoutSelSysPll);
139+
#elif DT_SAME_NODE(DT_CLOCKS_CTLR(MCUX_SCG_CLOCK_NODE(clkout_clk)), MCUX_SCG_CLOCK_NODE(lpfll_clk))
140+
CLOCK_SetClkOutSel(kClockClkoutSelSysLpfll);
139141
#else
140142
#error Unsupported SCG clkout clock source
141143
#endif

dts/arm/nxp/nxp_ke1xz.dtsi

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -89,9 +89,16 @@
8989
#clock-cells = <0>;
9090
};
9191

92+
lpfll_clk: lpfll_clk {
93+
compatible = "fixed-clock";
94+
clock-frequency = <72000000>;
95+
#clock-cells = <0>;
96+
};
97+
9298
core_clk: core_clk {
9399
compatible = "fixed-factor-clock";
94-
clocks = <&firc_clk>;
100+
#clocks = <&firc_clk>;
101+
clocks = <&lpfll_clk>;
95102
clock-div = <1>;
96103
#clock-cells = <0>;
97104
};

include/zephyr/dt-bindings/clock/kinetis_scg.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -29,5 +29,6 @@
2929
#define KINETIS_SCG_FIRC_ASYNC_DIV2_CLK 13U
3030
#define KINETIS_SCG_SPLL_ASYNC_DIV1_CLK 14U
3131
#define KINETIS_SCG_SPLL_ASYNC_DIV2_CLK 15U
32+
#define KINETIS_SCG_LPFLL_CLK 16U
3233

3334
#endif /* ZEPHYR_INCLUDE_DT_BINDINGS_CLOCK_KINETIS_SCG_H_ */

soc/nxp/kinetis/ke1xz/soc.c

Lines changed: 77 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -43,13 +43,17 @@ static const scg_sys_clk_config_t scg_sys_clk_config = {
4343
.src = kSCG_SysClkSrcSirc,
4444
#elif DT_SAME_NODE(DT_CLOCKS_CTLR(SCG_CLOCK_NODE(core_clk)), SCG_CLOCK_NODE(firc_clk))
4545
.src = kSCG_SysClkSrcFirc,
46+
#elif DT_SAME_NODE(DT_CLOCKS_CTLR(SCG_CLOCK_NODE(core_clk)), SCG_CLOCK_NODE(lpfll_clk))
47+
.src = kSCG_SysClkSrcLpFll,
48+
#else
49+
#error Invalid SCG core clock selected
4650
#endif
4751
};
4852

4953
/* Slow Internal Reference Clock (SIRC) configuration */
5054
ASSERT_ASYNC_CLK_DIV_VALID(SCG_CLOCK_DIV(sircdiv2_clk),
5155
"Invalid SCG SIRC divider 2 value");
52-
static const scg_sirc_config_t scg_sirc_config = {
56+
static scg_sirc_config_t scg_sirc_config = {
5357
.enableMode = kSCG_SircEnable,
5458
.div2 = TO_ASYNC_CLK_DIV(SCG_CLOCK_DIV(sircdiv2_clk)),
5559
#if MHZ(2) == DT_PROP(SCG_CLOCK_NODE(sirc_clk), clock_frequency)
@@ -66,7 +70,7 @@ ASSERT_ASYNC_CLK_DIV_VALID(SCG_CLOCK_DIV(fircdiv2_clk),
6670
"Invalid SCG FIRC divider 2 value");
6771
static const scg_firc_config_t scg_firc_config = {
6872
.enableMode = kSCG_FircEnable,
69-
.div2 = TO_ASYNC_CLK_DIV(SCG_CLOCK_DIV(fircdiv2_clk)), /* b20253 */
73+
.div2 = TO_ASYNC_CLK_DIV(SCG_CLOCK_DIV(fircdiv2_clk)),
7074
#if MHZ(48) == DT_PROP(SCG_CLOCK_NODE(firc_clk), clock_frequency)
7175
.range = kSCG_FircRange48M,
7276
#elif MHZ(52) == DT_PROP(SCG_CLOCK_NODE(firc_clk), clock_frequency)
@@ -81,31 +85,82 @@ static const scg_firc_config_t scg_firc_config = {
8185
.trimConfig = NULL
8286
};
8387

84-
__weak void clk_init(void)
88+
const scg_sosc_config_t scgSysOscConfig = {
89+
.freq = 8000000U, /* System Oscillator frequency: 8000000Hz */
90+
.enableMode = kSCG_SysOscEnable |
91+
kSCG_SysOscEnableInLowPower, /* Enable System OSC clock in low power mode */
92+
.monitorMode = kSCG_SysOscMonitorDisable, /* Monitor disabled */
93+
.div2 = kSCG_AsyncClkDivBy1, /* System OSC Clock Divider 2: divided by 1 */
94+
.workMode = kSCG_SysOscModeOscLowPower, /* Oscillator low power */
95+
};
96+
const scg_sirc_config_t scgSircConfig = {
97+
.enableMode = kSCG_SircEnable, /* Enable SIRC clock */
98+
.div2 = kSCG_AsyncClkDivBy2, /* Slow IRC Clock Divider 2: divided by 2 */
99+
.range = kSCG_SircRangeHigh, /* Slow IRC high range clock (8 MHz) */
100+
};
101+
const scg_firc_config_t scgFircConfig = {
102+
.enableMode = kSCG_FircEnable, /* Enable FIRC clock */
103+
.div2 = kSCG_AsyncClkDivBy1, /* Fast IRC Clock Divider 2: divided by 1 */
104+
.range = kSCG_FircRange48M, /* Fast IRC is trimmed to 48MHz */
105+
.trimConfig = NULL, /* Fast IRC Trim disabled */
106+
};
107+
const scg_lpfll_config_t scgLpFllConfig = {
108+
.enableMode = kSCG_LpFllEnable, /* Enable LPFLL clock */
109+
.div2 = kSCG_AsyncClkDivBy2, /* Low Power FLL Clock Divider 2: divided by 2 */
110+
.range = kSCG_LpFllRange72M, /* LPFLL is trimmed to 72MHz */
111+
.trimConfig = NULL,
112+
};
113+
114+
static void CLOCK_CONFIG_FircSafeConfig(const scg_firc_config_t *fircConfig)
85115
{
86-
const scg_sys_clk_config_t scg_sys_clk_config_safe = {
87-
.divSlow = kSCG_SysClkDivBy4,
88-
.divCore = kSCG_SysClkDivBy1,
89-
.src = kSCG_SysClkSrcSirc
90-
};
91-
scg_sys_clk_config_t current;
92-
93-
/* Configure SIRC */
94-
CLOCK_InitSirc(&scg_sirc_config);
95-
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);
116+
scg_sys_clk_config_t curConfig;
117+
const scg_sirc_config_t scgSircConfig = {.enableMode = kSCG_SircEnable,
118+
.div2 = kSCG_AsyncClkDivBy2,
119+
.range = kSCG_SircRangeHigh};
120+
scg_sys_clk_config_t sysClkSafeConfigSource = {
121+
.divSlow = kSCG_SysClkDivBy4, /* Slow clock divider */
122+
.divCore = kSCG_SysClkDivBy1, /* Core clock divider */
123+
.src = kSCG_SysClkSrcSirc /* System clock source */
124+
};
125+
/* Init Sirc. */
126+
CLOCK_InitSirc(&scgSircConfig);
127+
/* Change to use SIRC as system clock source to prepare to change FIRCCFG register. */
128+
CLOCK_SetRunModeSysClkConfig(&sysClkSafeConfigSource);
129+
/* Wait for clock source switch finished. */
130+
do {
131+
CLOCK_GetCurSysClkConfig(&curConfig);
132+
} while (curConfig.src != sysClkSafeConfigSource.src);
133+
134+
/* Init Firc. */
135+
CLOCK_InitFirc(fircConfig);
136+
/* Change back to use FIRC as system clock source in order to configure SIRC if needed. */
137+
sysClkSafeConfigSource.src = kSCG_SysClkSrcFirc;
138+
CLOCK_SetRunModeSysClkConfig(&sysClkSafeConfigSource);
139+
/* Wait for clock source switch finished. */
140+
do {
141+
CLOCK_GetCurSysClkConfig(&curConfig);
142+
} while (curConfig.src != sysClkSafeConfigSource.src);
143+
}
144+
102145

103-
/* Only RUN mode supported for now */
104-
CLOCK_SetRunModeSysClkConfig(&scg_sys_clk_config);
146+
__weak void clk_init(void)
147+
{
148+
scg_sys_clk_config_t current;
149+
150+
/* Init SOSC according to board configuration. */
151+
/* Init FIRC. */
152+
CLOCK_CONFIG_FircSafeConfig(&scgFircConfig);
153+
/* Init SIRC. */
154+
CLOCK_InitSirc(&scgSircConfig);
155+
/* Init LPFLL. */
156+
CLOCK_InitLpFll(&scgLpFllConfig);
157+
/* Finally init the App desired clock */
158+
CLOCK_SetRunModeSysClkConfig(&scg_sys_clk_config);
105159
do {
106-
CLOCK_GetCurSysClkConfig(&current);
160+
CLOCK_GetCurSysClkConfig(&current);
107161
} while (current.src != scg_sys_clk_config.src);
108162

163+
109164
#if DT_NODE_HAS_STATUS_OKAY(DT_NODELABEL(lpuart0))
110165
CLOCK_SetIpSrc(kCLOCK_Lpuart0,
111166
DT_CLOCKS_CELL(DT_NODELABEL(lpuart0), ip_source));

0 commit comments

Comments
 (0)