Skip to content

Commit 64c7cf7

Browse files
committed
drivers: added clock control driver for MSPM0
added clock_control support for TI MSPM0 Family Signed-off-by: Jackson Farley <[email protected]>
1 parent 488c8da commit 64c7cf7

File tree

5 files changed

+172
-0
lines changed

5 files changed

+172
-0
lines changed

drivers/clock_control/CMakeLists.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@ zephyr_library_sources_ifdef(CONFIG_CLOCK_CONTROL_MCUX_SCG_K4 clock_cont
2020
zephyr_library_sources_ifdef(CONFIG_CLOCK_CONTROL_MCUX_SIM clock_control_mcux_sim.c)
2121
zephyr_library_sources_ifdef(CONFIG_CLOCK_CONTROL_MCUX_SYSCON clock_control_mcux_syscon.c)
2222
zephyr_library_sources_ifdef(CONFIG_CLOCK_CONTROL_NPCM clock_control_npcm.c)
23+
zephyr_library_sources_ifdef(CONFIG_CLOCK_CONTROL_MSPM0 clock_control_mspm0.c)
2324
zephyr_library_sources_ifdef(CONFIG_CLOCK_CONTROL_NPCX clock_control_npcx.c)
2425
zephyr_library_sources_ifdef(CONFIG_CLOCK_CONTROL_NRF clock_control_nrf.c)
2526
zephyr_library_sources_ifdef(CONFIG_CLOCK_CONTROL_NRF_DRIVER_CALIBRATION nrf_clock_calibration.c)

drivers/clock_control/Kconfig

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -52,6 +52,8 @@ source "drivers/clock_control/Kconfig.mcux_syscon"
5252

5353
source "drivers/clock_control/Kconfig.npcm"
5454

55+
source "drivers/clock_control/Kconfig.mspm0"
56+
5557
source "drivers/clock_control/Kconfig.npcx"
5658

5759
source "drivers/clock_control/Kconfig.rv32m1"
Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
# TI MSPM0 Family
2+
3+
# Copyright (c) 2024, Texas Instruments Inc.
4+
# SPDX-License-Identifier: Apache-2.0
5+
6+
config CLOCK_CONTROL_MSPM0
7+
bool "TI MSPM0 clock"
8+
default y
9+
depends on SOC_FAMILY_TI_MSPM0
10+
help
11+
This option enables the TI MSPM0 Clock Control Enabler
12+
13+
config CLOCK_CONTROL_MSPM0_USE_PLL
14+
bool "TI MSPM0 Use PLL"
15+
default n
16+
help
17+
This option enables the PLL on MSPM0 devices (if equipped)
Lines changed: 134 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,134 @@
1+
/*
2+
* Copyright (c) 2024 Texas Instruments
3+
*
4+
* SPDX-License-Identifier: Apache-2.0
5+
*/
6+
7+
#include <zephyr/drivers/clock_control.h>
8+
#include <zephyr/drivers/clock_control/mspm0_clock_control.h>
9+
10+
#include <ti/driverlib/driverlib.h>
11+
12+
#define ULPCLK_DIV CONCAT(DL_SYSCTL_ULPCLK_DIV_, DT_PROP(DT_NODELABEL(clkmux), uclk_div))
13+
14+
#if DT_NODE_HAS_STATUS(DT_NODELABEL(pll), okay)
15+
#define MSPM0_PLL_ENABLED 1
16+
#endif
17+
18+
static const DL_SYSCTL_SYSPLLConfig clock_mspm0_cfg_syspll;
19+
20+
static int clock_mspm0_on(const struct device *dev, clock_control_subsys_t sys)
21+
{
22+
return 0;
23+
}
24+
25+
static int clock_mspm0_off(const struct device *dev, clock_control_subsys_t sys)
26+
{
27+
return 0;
28+
}
29+
30+
static enum clock_control_status clock_mspm0_get_status(const struct device *dev,
31+
clock_control_subsys_t sys)
32+
{
33+
return CLOCK_CONTROL_STATUS_UNKNOWN;
34+
}
35+
36+
static int clock_mspm0_get_rate(const struct device *dev, clock_control_subsys_t sys,
37+
uint32_t *rate)
38+
{
39+
struct mspm0_clockSys *clockSys = (struct mspm0_clockSys *)sys;
40+
uint8_t rateNotFound = 0;
41+
42+
switch (clockSys->bus) {
43+
case MSPM0_CLOCK_BUS_LFCLK:
44+
*rate = 32768;
45+
break;
46+
case MSPM0_CLOCK_BUS_ULPCLK:
47+
*rate = CONFIG_SYS_CLOCK_HW_CYCLES_PER_SEC /
48+
DT_PROP(DT_NODELABEL(clkmux), uclk_div);
49+
break;
50+
case MSPM0_CLOCK_BUS_MCLK:
51+
*rate = CONFIG_SYS_CLOCK_HW_CYCLES_PER_SEC;
52+
break;
53+
case MSPM0_CLOCK_BUS_MFPCLK:
54+
*rate = 4000000;
55+
break;
56+
case MSPM0_CLOCK_BUS_MFCLK:
57+
case MSPM0_CLOCK_BUS_CANCLK:
58+
default:
59+
rateNotFound = 1;
60+
break;
61+
}
62+
if (rateNotFound == 1) {
63+
return -ENOTSUP;
64+
} else {
65+
return 0;
66+
}
67+
}
68+
69+
static int clock_mspm0_set_rate(const struct device *dev, clock_control_subsys_t sys,
70+
clock_control_subsys_rate_t rate)
71+
{
72+
return -ENOTSUP;
73+
}
74+
75+
static int clock_mspm0_configure(const struct device *dev, clock_control_subsys_t sys, void *data)
76+
{
77+
return -ENOTSUP;
78+
}
79+
80+
static int clock_mspm0_init(const struct device *dev)
81+
{
82+
/* setup clocks based on specific rates */
83+
DL_SYSCTL_setSYSOSCFreq(DL_SYSCTL_SYSOSC_FREQ_BASE);
84+
85+
DL_SYSCTL_configSYSPLL((DL_SYSCTL_SYSPLLConfig *)&clock_mspm0_cfg_syspll);
86+
87+
DL_SYSCTL_setULPCLKDivider(ULPCLK_DIV);
88+
DL_SYSCTL_setMCLKSource(SYSOSC, HSCLK, DL_SYSCTL_HSCLK_SOURCE_SYSPLL);
89+
90+
return 0;
91+
}
92+
93+
static const struct clock_control_driver_api clock_mspm0_driver_api = {
94+
.on = clock_mspm0_on,
95+
.off = clock_mspm0_off,
96+
.get_status = clock_mspm0_get_status,
97+
.get_rate = clock_mspm0_get_rate,
98+
.set_rate = clock_mspm0_set_rate,
99+
.configure = clock_mspm0_configure};
100+
101+
DEVICE_DT_DEFINE(DT_NODELABEL(clkmux), &clock_mspm0_init, NULL, NULL, NULL, PRE_KERNEL_1,
102+
CONFIG_CLOCK_CONTROL_INIT_PRIORITY, &clock_mspm0_driver_api);
103+
104+
#if MSPM0_PLL_ENABLED
105+
106+
/* basic checks of the devicetree to follow */
107+
#if (DT_NODE_HAS_PROP(DT_NODELABEL(pll), clk2x_div) && \
108+
DT_NODE_HAS_PROP(DT_NODELABEL(pll), clk0_div))
109+
#error "Only CLK2X or CLK0 can be enabled at a time on the PLL"
110+
#endif
111+
112+
#define GENERATE_PLL_STRUCT() \
113+
static const DL_SYSCTL_SYSPLLConfig clock_mspm0_cfg_syspll = { \
114+
.inputFreq = DL_SYSCTL_SYSPLL_INPUT_FREQ_32_48_MHZ, \
115+
.rDivClk2x = (DT_PROP_OR(DT_NODELABEL(pll), clk2x_div, 1) - 1), \
116+
.rDivClk1 = (DT_PROP_OR(DT_NODELABEL(pll), clk1_div, 1) - 1), \
117+
.rDivClk0 = (DT_PROP_OR(DT_NODELABEL(pll), clk0_div, 1) - 1), \
118+
.qDiv = (DT_PROP(DT_NODELABEL(pll), q_div) - 1), \
119+
.pDiv = CONCAT(DL_SYSCTL_SYSPLL_PDIV_, DT_PROP(DT_NODELABEL(pll), p_div)), \
120+
.sysPLLMCLK = COND_CODE_1(DT_NODE_HAS_PROP(DT_NODELABEL(pll), clk2x_div), \
121+
(DL_SYSCTL_SYSPLL_MCLK_CLK2X), (DL_SYSCTL_SYSPLL_MCLK_CLK0)), \
122+
.enableCLK2x = COND_CODE_1(DT_NODE_HAS_PROP(DT_NODELABEL(pll), clk2x_div), \
123+
(DL_SYSCTL_SYSPLL_CLK2X_ENABLE), (DL_SYSCTL_SYSPLL_CLK2X_DISABLE)), \
124+
.enableCLK1 = COND_CODE_1(DT_NODE_HAS_PROP(DT_NODELABEL(pll), clk1_div), \
125+
(DL_SYSCTL_SYSPLL_CLK1_ENABLE), (DL_SYSCTL_SYSPLL_CLK1_DISABLE)), \
126+
.enableCLK0 = COND_CODE_1(DT_NODE_HAS_PROP(DT_NODELABEL(pll), clk0_div), \
127+
(DL_SYSCTL_SYSPLL_CLK0_ENABLE), (DL_SYSCTL_SYSPLL_CLK0_DISABLE)), \
128+
.sysPLLRef = COND_CODE_1(DT_CLOCKS_CELL(DT_NODELABEL(pll), clocks), \
129+
(DL_SYSCTL_SYSPLL_REF_HFCLK), (DL_SYSCTL_SYSPLL_REF_SYSOSC)), \
130+
};
131+
132+
GENERATE_PLL_STRUCT()
133+
134+
#endif /* MSPM0_PLL_ENABLED */
Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
/*
2+
* Copyright (c) 2024 Texas Instruments Inc.
3+
*
4+
* SPDX-License-Identifier: Apache-2.0
5+
*/
6+
7+
#ifndef ZEPHYR_INCLUDE_DRIVERS_CLOCK_CONTROL_MSPM0_CLOCK_CONTROL
8+
#define ZEPHYR_INCLUDE_DRIVERS_CLOCK_CONTROL_MSPM0_CLOCK_CONTROL
9+
10+
#include <zephyr/dt-bindings/clock/mspm0_clock.h>
11+
12+
struct mspm0_clockSys {
13+
uint32_t bus;
14+
};
15+
16+
#define MSPM0_CLOCK_SUBSYS_FN(index) {.bus = DT_INST_CLOCKS_CELL(index, bus)}
17+
18+
#endif /* ZEPHYR_INCLUDE_DRIVERS_CLOCK_CONTROL_MSPM0_CLOCK_CONTROL */

0 commit comments

Comments
 (0)