@@ -163,8 +163,8 @@ void runtime_init_clocks(void) {
163
163
164
164
bi_decl (bi_ptr_int32 (0 , 0 , rosc_div , 2 )); // default divider 2
165
165
bi_decl (bi_ptr_int32 (0 , 0 , rosc_drive , 0x0000 )); // default drives of 0
166
- bi_decl (bi_ptr_int32 (0 , 0 , xosc_mhz , 12 )); // xosc freq in MHz
167
- bi_decl (bi_ptr_int32 (0 , 0 , clk_mhz , 150 )); // xosc freq in MHz
166
+ bi_decl (bi_ptr_int32 (0 , 0 , xosc_hz , 12000000 )); // xosc freq in Hz
167
+ bi_decl (bi_ptr_int32 (0 , 0 , clk_khz , 150 * KHZ )); // maximum clk_sys freq in KHz
168
168
169
169
// Bump up ROSC speed to ~90MHz
170
170
rosc_hw -> freqa = 0 ; // reset the drive strengths
@@ -185,51 +185,50 @@ void runtime_init_clocks(void) {
185
185
ROSC_FREQB_DS7_LSB | ROSC_FREQB_DS6_LSB | ROSC_FREQB_DS5_LSB | ROSC_FREQB_DS4_LSB ;
186
186
187
187
// Calibrate ROSC frequency if XOSC present - otherwise just configure
188
- uint32_t rosc_freq_mhz = 0 ;
189
- if (xosc_mhz ) {
188
+ if (xosc_hz ) {
190
189
xosc_init ();
191
190
// Switch away from ROSC to avoid overclocking
192
191
// CLK_REF = XOSC
193
192
clock_configure_int_divider (clk_ref ,
194
193
CLOCKS_CLK_REF_CTRL_SRC_VALUE_XOSC_CLKSRC ,
195
194
0 ,
196
- xosc_mhz * MHZ ,
195
+ xosc_hz ,
197
196
1 );
198
197
// CLK_SYS = CLK_REF
199
198
clock_configure_int_divider (clk_sys ,
200
199
CLOCKS_CLK_SYS_CTRL_SRC_VALUE_CLK_REF ,
201
200
CLOCKS_CLK_SYS_CTRL_AUXSRC_VALUE_ROSC_CLKSRC , // leave the aux source on ROSC to prevent glitches when we switch back to it
202
- xosc_mhz * MHZ ,
201
+ xosc_hz ,
203
202
1 );
204
203
205
- // Max out rosc now we've switched away from it
206
- rosc_hw -> div = 1 | ROSC_DIV_VALUE_PASS ;
207
- rosc_hw -> freqa = (ROSC_FREQA_PASSWD_VALUE_PASS << ROSC_FREQA_PASSWD_LSB ) |
208
- ROSC_FREQA_DS3_BITS | ROSC_FREQA_DS2_BITS | // maximum drive
209
- ROSC_FREQA_DS1_RANDOM_BITS | ROSC_FREQA_DS0_RANDOM_BITS ; // enable randomisation
210
-
211
- // Wait for ROSC to be stable
212
- while (!(rosc_hw -> status & ROSC_STATUS_STABLE_BITS )) {
213
- tight_loop_contents ();
204
+ // Go through configurations until you get below 150MHz
205
+ uint8_t div = 1 ;
206
+ uint32_t drives = 0x7777 ;
207
+ while (div < 4 ) {
208
+ rosc_hw -> div = div | ROSC_DIV_VALUE_PASS ;
209
+ rosc_hw -> freqa = (ROSC_FREQA_PASSWD_VALUE_PASS << ROSC_FREQA_PASSWD_LSB ) |
210
+ drives |
211
+ ROSC_FREQA_DS1_RANDOM_BITS | ROSC_FREQA_DS0_RANDOM_BITS ; // enable randomisation
212
+
213
+ // Wait for ROSC to be stable
214
+ while (!(rosc_hw -> status & ROSC_STATUS_STABLE_BITS )) {
215
+ tight_loop_contents ();
216
+ }
217
+
218
+ if (frequency_count_khz (CLOCKS_FC0_SRC_VALUE_ROSC_CLKSRC_PH ) < clk_khz ) {
219
+ break ;
220
+ }
221
+
222
+ if (!drives ) div ++ ;
223
+ drives = drives ? 0x0000 : 0x7777 ;
214
224
}
215
-
216
- rosc_freq_mhz = frequency_count_khz (CLOCKS_FC0_SRC_VALUE_ROSC_CLKSRC_PH ) / KHZ ;
217
- }
218
- if (rosc_freq_mhz > clk_mhz ) {
219
- // CLK SYS = ROSC divided down to clk_mhz, according to XOSC calibration
220
- clock_configure_mhz (clk_sys ,
221
- CLOCKS_CLK_SYS_CTRL_SRC_VALUE_CLKSRC_CLK_SYS_AUX ,
222
- CLOCKS_CLK_SYS_CTRL_AUXSRC_VALUE_ROSC_CLKSRC ,
223
- rosc_freq_mhz ,
224
- clk_mhz );
225
- } else { // Either ROSC is running too slowly, or there was no XOSC to calibrate it against
226
- // CLK SYS = ROSC directly, as it's running slowly enough
227
- clock_configure_int_divider (clk_sys ,
228
- CLOCKS_CLK_SYS_CTRL_SRC_VALUE_CLKSRC_CLK_SYS_AUX ,
229
- CLOCKS_CLK_SYS_CTRL_AUXSRC_VALUE_ROSC_CLKSRC ,
230
- ROSC_HZ , // this doesn't have to be accurate
231
- 1 );
232
225
}
226
+ // CLK SYS = ROSC directly, as it's running slowly enough
227
+ clock_configure_int_divider (clk_sys ,
228
+ CLOCKS_CLK_SYS_CTRL_SRC_VALUE_CLKSRC_CLK_SYS_AUX ,
229
+ CLOCKS_CLK_SYS_CTRL_AUXSRC_VALUE_ROSC_CLKSRC ,
230
+ ROSC_HZ , // this doesn't have to be accurate
231
+ 1 );
233
232
234
233
// Configure other clocks - none of these need to be accurate
235
234
0 commit comments