23
23
#define HPSYS_RCC_CSR offsetof(HPSYS_RCC_TypeDef, CSR)
24
24
#define HPSYS_RCC_CFGR offsetof(HPSYS_RCC_TypeDef, CFGR)
25
25
#define HPSYS_RCC_DLL1CR offsetof(HPSYS_RCC_TypeDef, DLL1CR)
26
+ #define HPSYS_RCC_DLL2CR offsetof(HPSYS_RCC_TypeDef, DLL2CR)
26
27
27
28
#define HPSYS_RCC_CSR_SEL_SYS_CLK_HXT48 FIELD_PREP(HPSYS_RCC_CSR_SEL_SYS_Msk, 1U)
28
29
#define HPSYS_RCC_CSR_SEL_SYS_CLK_DLL1 FIELD_PREP(HPSYS_RCC_CSR_SEL_SYS_Msk, 3U)
30
+ #define HPSYS_RCC_CSR_SEL_MPI1_CLK_DLL2 FIELD_PREP(HPSYS_RCC_CSR_SEL_MPI1_Msk, 2U)
31
+ #define HPSYS_RCC_CSR_SEL_MPI2_CLK_DLL2 FIELD_PREP(HPSYS_RCC_CSR_SEL_MPI2_Msk, 2U)
29
32
#define HPSYS_RCC_CSR_SEL_PERI_CLK_HXT48 FIELD_PREP(HPSYS_RCC_CSR_SEL_PERI_Msk, 1U)
30
33
31
- #define HPSYS_RCC_DLL1CR_STG_STEP 24000000UL
32
-
33
- struct clock_control_sf32lb_rcc_dll_config {
34
- bool enabled ;
35
- uintptr_t pmuc ;
36
- uint32_t freq ;
37
- };
34
+ #define HPSYS_RCC_DLLXCR_EN HPSYS_RCC_DLL1CR_EN
35
+ #define HPSYS_RCC_DLLXCR_STG_Msk HPSYS_RCC_DLL1CR_STG_Msk
36
+ #define HPSYS_RCC_DLLXCR_STG_STEP 24000000UL
37
+ #define HPSYS_RCC_DLLXCR_IN_DIV2_EN HPSYS_RCC_DLL1CR_IN_DIV2_EN
38
+ #define HPSYS_RCC_DLLXCR_OUT_DIV2_EN HPSYS_RCC_DLL1CR_OUT_DIV2_EN
39
+ #define HPSYS_RCC_DLLXCR_READY HPSYS_RCC_DLL1CR_READY
38
40
39
41
struct clock_control_sf32lb_rcc_config {
40
42
uintptr_t base ;
41
43
uintptr_t cfg ;
44
+ uintptr_t pmuc ;
42
45
uint8_t hdiv ;
43
46
uint8_t pdiv1 ;
44
47
uint8_t pdiv2 ;
45
- struct clock_control_sf32lb_rcc_dll_config dll1 ;
48
+ uint32_t dll1_freq ;
49
+ uint32_t dll2_freq ;
46
50
const struct device * hxt48 ;
47
51
};
48
52
53
+ static inline void configure_dll (const struct device * dev , uint32_t freq , uint32_t dllxcr )
54
+ {
55
+ const struct clock_control_sf32lb_rcc_config * config = dev -> config ;
56
+ uint32_t val ;
57
+
58
+ /* disable DLLX, clear modified fields */
59
+ val = sys_read32 (config -> base + dllxcr );
60
+ val &= ~HPSYS_RCC_DLLXCR_EN ;
61
+ sys_write32 (val , config -> base + dllxcr );
62
+
63
+ /* configure DLLX */
64
+ val &= ~(HPSYS_RCC_DLLXCR_STG_Msk | HPSYS_RCC_DLLXCR_OUT_DIV2_EN );
65
+ val |= FIELD_PREP (HPSYS_RCC_DLLXCR_STG_Msk , (freq / HPSYS_RCC_DLLXCR_STG_STEP ) - 1U ) |
66
+ HPSYS_RCC_DLLXCR_IN_DIV2_EN | HPSYS_RCC_DLLXCR_EN ;
67
+ sys_write32 (val , config -> base + dllxcr );
68
+
69
+ do {
70
+ val = sys_read32 (config -> base + dllxcr );
71
+ } while ((val & HPSYS_RCC_DLLXCR_READY ) == 0U );
72
+ }
73
+
49
74
static int clock_control_sf32lb_rcc_on (const struct device * dev , clock_control_subsys_t sys )
50
75
{
51
76
const struct clock_control_sf32lb_rcc_config * config = dev -> config ;
@@ -108,35 +133,33 @@ static int clock_control_sf32lb_rcc_init(const struct device *dev)
108
133
sys_write32 (val , config -> base + HPSYS_RCC_CSR );
109
134
}
110
135
111
- if (config -> dll1 . enabled ) {
112
- val = sys_read32 (config -> dll1 . pmuc + PMUC_HXT_CR1 );
136
+ if (config -> dll1_freq != 0U || config -> dll2_freq != 0U ) {
137
+ val = sys_read32 (config -> pmuc + PMUC_HXT_CR1 );
113
138
val |= PMUC_HXT_CR1_BUF_DLL_EN ;
114
- sys_write32 (val , config -> dll1 . pmuc + PMUC_HXT_CR1 );
139
+ sys_write32 (val , config -> pmuc + PMUC_HXT_CR1 );
115
140
116
141
val = sys_read32 (config -> cfg + HPSYS_CFG_CAU2_CR );
117
142
val |= HPSYS_CFG_CAU2_CR_HPBG_EN | HPSYS_CFG_CAU2_CR_HPBG_VDDPSW_EN ;
118
143
sys_write32 (val , config -> cfg + HPSYS_CFG_CAU2_CR );
119
144
120
- /* disable DLL1, clear modified fields */
121
- val = sys_read32 (config -> base + HPSYS_RCC_DLL1CR );
122
- val &= ~HPSYS_RCC_DLL1CR_EN ;
123
- sys_write32 (val , config -> base + HPSYS_RCC_DLL1CR );
145
+ val = sys_read32 (config -> base + HPSYS_RCC_CSR );
124
146
125
- /* configure DLL1 */
126
- val &= ~(HPSYS_RCC_DLL1CR_STG_Msk | HPSYS_RCC_DLL1CR_OUT_DIV2_EN );
127
- val |= FIELD_PREP (HPSYS_RCC_DLL1CR_STG_Msk ,
128
- (config -> dll1 .freq / HPSYS_RCC_DLL1CR_STG_STEP ) - 1U ) |
129
- HPSYS_RCC_DLL1CR_IN_DIV2_EN | HPSYS_RCC_DLL1CR_EN ;
130
- sys_write32 (val , config -> base + HPSYS_RCC_DLL1CR );
147
+ if (config -> dll1_freq != 0U ) {
148
+ configure_dll (dev , config -> dll1_freq , HPSYS_RCC_DLL1CR );
131
149
132
- do {
133
- val = sys_read32 (config -> base + HPSYS_RCC_DLL1CR );
134
- } while ((val & HPSYS_RCC_DLL1CR_READY ) == 0U );
150
+ /* TODO: make this configurable */
151
+ val &= ~HPSYS_RCC_CSR_SEL_SYS_Msk ;
152
+ val |= HPSYS_RCC_CSR_SEL_SYS_CLK_DLL1 ;
153
+ }
154
+
155
+ if (config -> dll2_freq != 0U ) {
156
+ configure_dll (dev , config -> dll2_freq , HPSYS_RCC_DLL2CR );
157
+
158
+ /* TODO: make this configurable */
159
+ val &= ~(HPSYS_RCC_CSR_SEL_MPI1_Msk | HPSYS_RCC_CSR_SEL_MPI2_Msk );
160
+ val |= HPSYS_RCC_CSR_SEL_MPI1_CLK_DLL2 | HPSYS_RCC_CSR_SEL_MPI2_CLK_DLL2 ;
161
+ }
135
162
136
- /* TODO: make this configurable */
137
- val = sys_read32 (config -> base + HPSYS_RCC_CSR );
138
- val &= ~HPSYS_RCC_CSR_SEL_SYS_Msk ;
139
- val |= HPSYS_RCC_CSR_SEL_SYS_CLK_DLL1 ;
140
163
sys_write32 (val , config -> base + HPSYS_RCC_CSR );
141
164
}
142
165
@@ -151,35 +174,45 @@ static int clock_control_sf32lb_rcc_init(const struct device *dev)
151
174
return 0 ;
152
175
}
153
176
154
- /* DLL1 requires HXT48 */
155
- IF_ENABLED (DT_NODE_HAS_STATUS (DT_INST_CHILD (0 , dll1 ), okay ), (
156
- BUILD_ASSERT (
177
+ /* DLL1/2 requires HXT48 */
178
+ IF_ENABLED (UTIL_OR (
179
+ DT_NODE_HAS_STATUS (DT_INST_CHILD (0 , dll1 ), okay ),
180
+ DT_NODE_HAS_STATUS (DT_INST_CHILD (0 , dll2 ), okay )),
181
+ (BUILD_ASSERT (
157
182
(DT_NODE_HAS_STATUS (DT_INST_CLOCKS_CTLR_BY_NAME (0 , hxt48 ), okay )),
158
- "DLL1 requires HXT48 to be enabled"
159
- );))
183
+ "DLL1/2 require HXT48 to be enabled" );))
160
184
161
- /* DLL1 frequency must be a multiple of step size */
185
+ /* DLL1/2 frequency must be a multiple of step size */
162
186
IF_ENABLED (DT_NODE_HAS_STATUS (DT_INST_CHILD (0 , dll1 ), okay ), (
163
187
BUILD_ASSERT (
164
188
((DT_PROP (DT_INST_CHILD (0 , dll1 ), clock_frequency ) != 0 ) &&
165
189
((DT_PROP (DT_INST_CHILD (0 , dll1 ), clock_frequency ) %
166
- HPSYS_RCC_DLL1CR_STG_STEP ) == 0 )),
190
+ HPSYS_RCC_DLLXCR_STG_STEP ) == 0 )),
167
191
"DLL1 frequency must be a non-zero multiple of "
168
- STRINGIFY (HPSYS_RCC_DLL1CR_STG_STEP )
192
+ STRINGIFY (HPSYS_RCC_DLLXCR_STG_STEP )
193
+ );))
194
+
195
+ IF_ENABLED (DT_NODE_HAS_STATUS (DT_INST_CHILD (0 , dll2 ), okay ), (
196
+ BUILD_ASSERT (
197
+ ((DT_PROP (DT_INST_CHILD (0 , dll2 ), clock_frequency ) != 0 ) &&
198
+ ((DT_PROP (DT_INST_CHILD (0 , dll2 ), clock_frequency ) %
199
+ HPSYS_RCC_DLLXCR_STG_STEP ) == 0 )),
200
+ "DLL2 frequency must be a non-zero multiple of "
201
+ STRINGIFY (HPSYS_RCC_DLLXCR_STG_STEP )
169
202
);))
170
203
171
204
static const struct clock_control_sf32lb_rcc_config config = {
172
205
.base = DT_REG_ADDR (DT_INST_PARENT (0 )),
173
206
.cfg = DT_REG_ADDR (DT_INST_PHANDLE (0 , sifli_cfg )),
207
+ .pmuc = DT_REG_ADDR (DT_INST_PHANDLE (0 , sifli_pmuc )),
174
208
.hxt48 = DEVICE_DT_GET_OR_NULL (DT_INST_CLOCKS_CTLR_BY_NAME (0 , hxt48 )),
175
209
.hdiv = DT_INST_PROP (0 , sifli_hdiv ),
176
210
.pdiv1 = DT_INST_PROP (0 , sifli_pdiv1 ),
177
211
.pdiv2 = DT_INST_PROP (0 , sifli_pdiv2 ),
178
- .dll1 = {
179
- .enabled = DT_NODE_HAS_STATUS (DT_INST_CHILD (0 , dll1 ), okay ),
180
- .pmuc = DT_REG_ADDR (DT_INST_PHANDLE (0 , sifli_pmuc )),
181
- .freq = DT_PROP (DT_INST_CHILD (0 , dll1 ), clock_frequency ),
182
- },
212
+ .dll1_freq = COND_CODE_1 (DT_NODE_HAS_STATUS (DT_INST_CHILD (0 , dll1 ), okay ),
213
+ (DT_PROP (DT_INST_CHILD (0 , dll1 ), clock_frequency )), (0U )),
214
+ .dll2_freq = COND_CODE_1 (DT_NODE_HAS_STATUS (DT_INST_CHILD (0 , dll2 ), okay ),
215
+ (DT_PROP (DT_INST_CHILD (0 , dll2 ), clock_frequency )), (0U )),
183
216
};
184
217
185
218
DEVICE_DT_INST_DEFINE (0 , clock_control_sf32lb_rcc_init , NULL , NULL , & config , PRE_KERNEL_1 ,
0 commit comments