10
#include "eliot1_board.h"
11
#include "hal_clkctr.h"
16
#define CLKCTR_PLLCFG_SEL_Pos (0UL)
17
#define CLKCTR_PLLCFG_SEL_Msk (0x1ffUL)
18
#define CLKCTR_PLLCFG_MAN_Pos (9UL)
19
#define CLKCTR_PLLCFG_MAN_Msk (0x200UL)
20
#define CLKCTR_PLLCFG_OD_MAN_Pos (10UL)
21
#define CLKCTR_PLLCFG_OD_MAN_Msk (0x3c00UL)
22
#define CLKCTR_PLLCFG_NF_MAN_Pos (14UL)
23
#define CLKCTR_PLLCFG_NF_MAN_Msk (0x7ffc000UL)
24
#define CLKCTR_PLLCFG_NR_MAN_Pos (27UL)
25
#define CLKCTR_PLLCFG_NR_MAN_Msk (0x78000000UL)
26
#define CLKCTR_PLLCFG_LOCK_Pos (31UL)
27
#define CLKCTR_PLLCFG_LOCK_Msk (0x80000000UL)
30
#define CLKCTR_CFG_FCLK_SCALE_EN_Pos (0UL)
31
#define CLKCTR_CFG_FCLK_SCALE_EN_Msk (0x1UL)
32
#define CLKCTR_CFG_MAINCLK_SEL_Pos (4UL)
33
#define CLKCTR_CFG_MAINCLK_SEL_Msk (0x30UL)
34
#define CLKCTR_CFG_PLLREF_SEL_Pos (6UL)
35
#define CLKCTR_CFG_PLLREF_SEL_Msk (0x40UL)
36
#define CLKCTR_CFG_USBCLK_SEL_Pos (7UL)
37
#define CLKCTR_CFG_USBCLK_SEL_Msk (0x80UL)
38
#define CLKCTR_CFG_I2SCLK_SEL_Pos (8UL)
39
#define CLKCTR_CFG_I2SCLK_SEL_Msk (0x100UL)
40
#define CLKCTR_CFG_MCO_SEL_Pos (9UL)
41
#define CLKCTR_CFG_MCO_SEL_Msk (0xe00UL)
42
#define CLKCTR_CFG_MCO_EN_Pos (13UL)
43
#define CLKCTR_CFG_MCO_EN_Msk (0x2000UL)
47
#define CLKCTR_FCLKDIV_FCLKDIV_Pos (0UL)
48
#define CLKCTR_FCLKDIV_FCLKDIV_Msk (0x1fUL)
49
#define CLKCTR_FCLKDIV_FCLKDIV_CUR_Pos (16UL)
50
#define CLKCTR_FCLKDIV_FCLKDIV_CUR_Msk (0x1f0000UL)
52
#define CLKCTR_SYSCLKDIV_STSCLKDIV_Pos (0UL)
53
#define CLKCTR_SYSCLKDIV_STSCLKDIV_Msk (0x1fUL)
54
#define CLKCTR_SYSCLKDIV_STSCLKDIV_CUR_Pos (16UL)
55
#define CLKCTR_SYSCLKDIV_STSCLKDIV_CUR_Msk (0x1f0000UL)
57
#define CLKCTR_QSPICLKDIV_QSPICLKDIV_Pos (0UL)
58
#define CLKCTR_QSPICLKDIV_QSPICLKDIV_Msk (0x1fUL)
59
#define CLKCTR_QSPICLKDIV_QSPICLKDIV_CUR_Pos (16UL)
60
#define CLKCTR_QSPICLKDIV_QSPICLKDIV_CUR_Msk (0x1f0000UL)
63
#define CLKCTR_GNSSCLKDIV_GNSSCLKDIV_Pos (0UL)
64
#define CLKCTR_GNSSCLKDIV_GNSSCLKDIV_Msk (0x7UL)
65
#define CLKCTR_GNSSCLKDIV_GNSSCLKDIV_CUR_Pos (16UL)
66
#define CLKCTR_GNSSCLKDIV_GNSSCLKDIV_CUR_Msk (0x70000UL)
68
#define CLKCTR_FORCE_CLK_DEV_EN 1
71
#define CLKCTR_PLL_CFG_NR_MAN(x) \
72
(((x) << CLKCTR_PLLCFG_NR_MAN_Pos) & CLKCTR_PLLCFG_NR_MAN_Msk)
73
#define CLKCTR_PLL_CFG_NF_MAN(x) \
74
(((x) << CLKCTR_PLLCFG_NF_MAN_Pos) & CLKCTR_PLLCFG_NF_MAN_Msk)
75
#define CLKCTR_PLL_CFG_OD_MAN(x) \
76
(((x) << CLKCTR_PLLCFG_OD_MAN_Pos) & CLKCTR_PLLCFG_OD_MAN_Msk)
77
#define CLKCTR_PLL_CFG_MAN(x) \
78
(((x)<< CLKCTR_PLLCFG_MAN_Pos) & CLKCTR_PLLCFG_MAN_Msk)
79
#define CLKCTR_PLL_CFG_SEL(x) \
80
(((x) << CLKCTR_PLLCFG_SEL_Pos) & CLKCTR_PLLCFG_SEL_Msk)
83
static uint32_t MAINCLK_FREQUENCY = BOARD_HFI_FREQUENCY;
85
int clkctr_get_pll_config(struct clkctr_regs *base,
86
struct clkctr_pll_cfg *config) {
87
uint32_t reg = base->PLLCFG;
89
config->lock = (reg & CLKCTR_PLLCFG_LOCK_Msk) >> CLKCTR_PLLCFG_LOCK_Pos;
90
config->nr_man = (reg & CLKCTR_PLLCFG_NR_MAN_Msk)
91
>> CLKCTR_PLLCFG_NR_MAN_Pos;
92
config->nf_man = (reg & CLKCTR_PLLCFG_NF_MAN_Msk)
93
>> CLKCTR_PLLCFG_NF_MAN_Pos;
94
config->od_man = (reg & CLKCTR_PLLCFG_OD_MAN_Msk)
95
>> CLKCTR_PLLCFG_OD_MAN_Pos;
96
config->man = (reg & CLKCTR_PLLCFG_MAN_Msk) >> CLKCTR_PLLCFG_MAN_Pos;
97
config->sel = (reg & CLKCTR_PLLCFG_SEL_Msk) >> CLKCTR_PLLCFG_SEL_Pos;
102
int clkctr_set_pll_config(struct clkctr_regs *base,
103
struct clkctr_pll_cfg config) {
104
uint32_t pll_cfg = CLKCTR_PLL_CFG_NR_MAN(
105
config.nr_man) | CLKCTR_PLL_CFG_NF_MAN(config.nr_man)
106
| CLKCTR_PLL_CFG_OD_MAN(config.od_man)
107
| CLKCTR_PLL_CFG_MAN(config.man)
108
| CLKCTR_PLL_CFG_SEL(config.sel);
110
if (config.sel != 0) {
114
base->PLLCFG = pll_cfg;
115
while ((base->PLLCFG & CLKCTR_PLLCFG_LOCK_Msk) == 0) {
119
base->PLLCFG = pll_cfg;
125
int clkctr_set_switch_main_clk(struct clkctr_regs *base, uint32_t value) {
126
uint32_t cfgReg = base->CFG;
128
cfgReg &= ~CLKCTR_CFG_MAINCLK_SEL_Msk;
129
cfgReg |= (value << CLKCTR_CFG_MAINCLK_SEL_Pos);
135
int clkctr_set_switch_pll_ref(struct clkctr_regs *base, uint32_t value) {
136
uint32_t cfgReg = base->CFG;
138
cfgReg &= ~(CLKCTR_CFG_PLLREF_SEL_Msk);
139
cfgReg |= (value << CLKCTR_CFG_PLLREF_SEL_Pos);
145
void clkctr_set_pll(struct clkctr_regs *base, uint32_t xti_hz, uint16_t pll_mul) {
146
struct clkctr_pll_cfg config;
148
clkctr_set_switch_main_clk(base, CLKCTR_CLK_TYPE_HFI);
149
clkctr_get_pll_config(base, &config);
151
clkctr_set_pll_config(base, config);
155
clkctr_set_switch_pll_ref(base, CLKCTR_CLK_TYPE_HFI);
156
MAINCLK_FREQUENCY = BOARD_HFI_FREQUENCY;
158
clkctr_set_switch_pll_ref(base, CLKCTR_CLK_TYPE_XTI);
159
MAINCLK_FREQUENCY = xti_hz;
162
if (pll_mul > PLL_MAX_MULTIPLIER) {
163
pll_mul = PLL_MAX_MULTIPLIER;
166
if ((MAINCLK_FREQUENCY * (pll_mul + 1)) > CLKCTR_PLLCLK_MAX) {
167
pll_mul = (CLKCTR_PLLCLK_MAX / MAINCLK_FREQUENCY) - 1;
170
if ((MAINCLK_FREQUENCY * (pll_mul + 1)) < CLKCTR_PLLCLK_OD_MIN) {
171
pll_mul = PLL_MIN_MULTIPLIER;
174
if (pll_mul > PLL_MIN_MULTIPLIER) {
175
clkctr_get_pll_config(base, &config);
177
config.sel = pll_mul;
178
clkctr_set_pll_config(base, config);
179
clkctr_set_switch_main_clk(base, CLKCTR_CLK_TYPE_PLL);
180
MAINCLK_FREQUENCY = MAINCLK_FREQUENCY * (pll_mul + 1);
184
uint32_t clk_get_sys_clk_div(struct clkctr_regs *base) {
185
return ((base->SYSCLKDIV & CLKCTR_SYSCLKDIV_STSCLKDIV_Msk)
186
>> CLKCTR_SYSCLKDIV_STSCLKDIV_Pos) + 1;
189
uint32_t clkctr_set_sys_clk_div(struct clkctr_regs *base, uint32_t value) {
191
base->SYSCLKDIV = ((value - 1) << CLKCTR_SYSCLKDIV_STSCLKDIV_Pos)
192
& CLKCTR_SYSCLKDIV_STSCLKDIV_Msk;
194
while (clk_get_sys_clk_div(base) != value)
200
uint32_t clkctr_get_fclk_div(struct clkctr_regs *base) {
201
return ((base->FCLKDIV & CLKCTR_FCLKDIV_FCLKDIV_Msk)
202
>> CLKCTR_FCLKDIV_FCLKDIV_Pos) + 1;
205
uint32_t clkctr_set_fclk_div(struct clkctr_regs *base, uint32_t value) {
207
base->FCLKDIV = ((value - 1) << CLKCTR_FCLKDIV_FCLKDIV_Pos)
208
& CLKCTR_FCLKDIV_FCLKDIV_Msk;
210
while (clkctr_get_fclk_div(base) != value) {
217
uint32_t clkctr_get_qspi_clk_div(struct clkctr_regs *base) {
218
return ((base->QSPICLKDIV & CLKCTR_QSPICLKDIV_QSPICLKDIV_Msk)
219
>> CLKCTR_QSPICLKDIV_QSPICLKDIV_Pos) + 1;
222
uint32_t clkctr_set_qspi_clk_div(struct clkctr_regs *base, uint32_t value) {
224
base->QSPICLKDIV = ((value - 1) << CLKCTR_QSPICLKDIV_QSPICLKDIV_Pos)
225
& CLKCTR_QSPICLKDIV_QSPICLKDIV_Msk;
227
while (clkctr_get_qspi_clk_div(base) != value) {
234
uint32_t clkctr_set_gnss_clk_div(struct clkctr_regs *base, uint32_t value) {
236
base->GNSSCLKDIV = ((value - 1) << CLKCTR_GNSSCLKDIV_GNSSCLKDIV_Pos)
237
& CLKCTR_GNSSCLKDIV_GNSSCLKDIV_Msk;
239
#ifdef CLKCTR_NO_GNNS_BUG_ELIOT1RTL_2
240
while (CLKCTR_GetGNSSClkDiv(base) != value)
247
void clkctr_set_sys_div(struct clkctr_regs *base, uint16_t fclk_div,
248
uint16_t sysclk_div, uint16_t gnssclk_div, uint16_t qspiclk_div) {
249
if (sysclk_div > CLKCTR_MAX_SYSCLK_DIV) {
250
sysclk_div = CLKCTR_MAX_SYSCLK_DIV;
252
clkctr_set_sys_clk_div(base, sysclk_div + 1);
254
if (fclk_div > CLKCTR_MAX_FCLK_DIV) {
255
fclk_div = CLKCTR_MAX_FCLK_DIV;
257
clkctr_set_fclk_div(base, fclk_div + 1);
259
if (gnssclk_div > CLKCTR_MAX_GNSSCLK_DIV) {
260
gnssclk_div = CLKCTR_MAX_GNSSCLK_DIV;
262
clkctr_set_gnss_clk_div(base, gnssclk_div + 1);
264
if (qspiclk_div > CLKCTR_MAX_QSPICLK_DIV) {
265
qspiclk_div = CLKCTR_MAX_QSPICLK_DIV;
267
clkctr_set_qspi_clk_div(base, qspiclk_div + 1);