Skip to content

Commit

Permalink
add PICO_USE_FASTEST_SUPPORTED_CLOCK, and support vreg setting and SY…
Browse files Browse the repository at this point in the history
…S_CLOCK_MHZ=200 for rp2040 (#2285)
  • Loading branch information
kilograham authored Feb 18, 2025
1 parent 7ce1ae8 commit c757f36
Show file tree
Hide file tree
Showing 11 changed files with 82 additions and 11 deletions.
9 changes: 9 additions & 0 deletions src/rp2040/hardware_regs/include/hardware/platform_defs.h
Original file line number Diff line number Diff line change
Expand Up @@ -61,16 +61,25 @@
#endif
#endif

// PICO_CONFIG: PICO_USE_FASTEST_SUPPORTED_CLOCK, Use the fastest officially supported clock by default, type=bool, default=0, group=hardware_base
#ifndef PICO_USE_FASTEST_SUPPORTED_CLOCK
#define PICO_USE_FASTEST_SUPPORTED_CLOCK 0
#endif

// PICO_CONFIG: SYS_CLK_HZ, System operating frequency in Hz, type=int, default=125000000, advanced=true, group=hardware_base
#ifndef SYS_CLK_HZ
#ifdef SYS_CLK_KHZ
#define SYS_CLK_HZ ((SYS_CLK_KHZ) * _u(1000))
#elif defined(SYS_CLK_MHZ)
#define SYS_CLK_HZ ((SYS_CLK_MHZ) * _u(1000000))
#else
#if PICO_USE_FASTEST_SUPPORTED_CLOCK
#define SYS_CLK_HZ _u(200000000)
#else
#define SYS_CLK_HZ _u(125000000)
#endif
#endif
#endif

// PICO_CONFIG: USB_CLK_HZ, USB clock frequency. Must be 48MHz for the USB interface to operate correctly, type=int, default=48000000, advanced=true, group=hardware_base
#ifndef USB_CLK_HZ
Expand Down
5 changes: 5 additions & 0 deletions src/rp2350/hardware_regs/include/hardware/platform_defs.h
Original file line number Diff line number Diff line change
Expand Up @@ -89,6 +89,11 @@
#endif
#endif

// PICO_CONFIG: PICO_USE_FASTEST_SUPPORTED_CLOCK, Use the fastest officially supported clock by default, type=bool, default=0, group=hardware_base
#ifndef PICO_USE_FASTEST_SUPPORTED_CLOCK
#define PICO_USE_FASTEST_SUPPORTED_CLOCK 0
#endif

// PICO_CONFIG: SYS_CLK_HZ, System operating frequency in Hz, type=int, default=150000000, advanced=true, group=hardware_base
#ifndef SYS_CLK_HZ
#ifdef SYS_CLK_KHZ
Expand Down
1 change: 1 addition & 0 deletions src/rp2_common/BUILD.bazel
Original file line number Diff line number Diff line change
Expand Up @@ -71,6 +71,7 @@ alias(
"//src/rp2_common/hardware_base:__pkg__",
"//src/rp2_common/hardware_irq:__pkg__",
"//src/rp2_common/hardware_pll:__pkg__",
"//src/rp2_common/hardware_vreg:__pkg__",
"//src/rp2_common/hardware_watchdog:__pkg__",
"//src/rp2_common/hardware_xosc:__pkg__",
"//src/rp2_common/pico_bit_ops:__pkg__",
Expand Down
6 changes: 5 additions & 1 deletion src/rp2_common/hardware_clocks/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -10,4 +10,8 @@ pico_mirrored_target_link_libraries(hardware_clocks INTERFACE
hardware_vreg
hardware_watchdog
hardware_xosc
)
)

if (PICO_USE_FASTEST_SUPPORTED_CLOCK)
target_compile_definitions(hardware_clocks INTERFACE PICO_USE_FASTEST_SUPPORTED_CLOCK=1)
endif()
30 changes: 30 additions & 0 deletions src/rp2_common/hardware_clocks/include/hardware/clocks.h
Original file line number Diff line number Diff line change
Expand Up @@ -206,6 +206,36 @@ extern "C" {
#endif
#endif // SYS_CLK_KHZ == 125000 && XOSC_KHZ == 12000 && PLL_COMMON_REFDIV == 1

#if PICO_RP2040 && (SYS_CLK_HZ == 200 * MHZ) && (XOSC_HZ == 12 * MHZ) && (PLL_SYS_REFDIV == 1)
// PICO_CONFIG: SYS_CLK_VREG_VOLTAGE_AUTO_ADJUST, Should the regulator voltage be adjusted above SYS_CLK_VREG_VOLTAGE_MIN when initializing the clocks, type=bool, default=0, advanced=true, group=hardware_clocks
#ifndef SYS_CLK_VREG_VOLTAGE_AUTO_ADJUST
#define SYS_CLK_VREG_VOLTAGE_AUTO_ADJUST 1
#endif
// PICO_CONFIG: SYS_CLK_VREG_VOLTAGE_MIN, minimum voltage (see VREG_VOLTAGE_x_xx) for the voltage regulator to be ensured during clock initialization if SYS_CLK_VREG_VOLTAGE_AUTO_ADJUST is 1, type=int, advanced=true, group=hardware_clocks
#if SYS_CLK_VREG_VOLTAGE_AUTO_ADJUST && !defined(SYS_CLK_VREG_VOLTAGE_MIN)
#define SYS_CLK_VREG_VOLTAGE_MIN VREG_VOLTAGE_1_15
#endif
// PLL settings for fast 200 MHz system clock on RP2040
#ifndef PLL_SYS_VCO_FREQ_HZ
#define PLL_SYS_VCO_FREQ_HZ (1200 * MHZ)
#endif
#ifndef PLL_SYS_POSTDIV1
#define PLL_SYS_POSTDIV1 6
#endif
#ifndef PLL_SYS_POSTDIV2
#define PLL_SYS_POSTDIV2 1
#endif
#else
#ifndef SYS_CLK_VREG_VOLTAGE_AUTO_ADJUST
#define SYS_CLK_VREG_VOLTAGE_AUTO_ADJUST 0
#endif
#endif // PICO_RP2040 && SYS_CLK_KHZ == 200000 && XOSC_KHZ == 12000 && PLL_COMMON_REFDIV == 1

// PICO_CONFIG: SYS_CLK_VREG_VOLTAGE_AUTO_ADJUST_DELAY_US, Number of microseconds to wait after updating regulator voltage due to SYS_CLK_VREG_VOLTAGE_MIN to allow voltage to settle, type=bool, default=1, advanced=true, group=hardware_clocks
#ifndef SYS_CLK_VREG_VOLTAGE_AUTO_ADJUST_DELAY_US
#define SYS_CLK_VREG_VOLTAGE_AUTO_ADJUST_DELAY_US 1000
#endif

#if !defined(PLL_SYS_VCO_FREQ_HZ) || !defined(PLL_SYS_POSTDIV1) || !defined(PLL_SYS_POSTDIV2)
#error PLL_SYS_VCO_FREQ_HZ, PLL_SYS_POSTDIV1 and PLL_SYS_POSTDIV2 must all be specified when using custom clock setup
#endif
Expand Down
2 changes: 1 addition & 1 deletion src/rp2_common/hardware_vreg/BUILD.bazel
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ cc_library(
target_compatible_with = compatible_with_rp2(),
deps = [
"//src/rp2_common:hardware_structs",
"//src/rp2_common:pico_platform",
"//src/rp2_common:pico_platform_internal",
"//src/rp2_common/hardware_base",
],
)
7 changes: 7 additions & 0 deletions src/rp2_common/hardware_vreg/include/hardware/vreg.h
Original file line number Diff line number Diff line change
Expand Up @@ -82,6 +82,13 @@ enum vreg_voltage {
void vreg_set_voltage(enum vreg_voltage voltage);


/*! \brief Get voltage
* \ingroup hardware_vreg
*
* \return The current voltage (from enumeration \ref vreg_voltage) of the voltage regulator
**/
enum vreg_voltage vreg_get_voltage(void);

/*! \brief Enable use of voltages beyond the safe range of operation
* \ingroup hardware_vreg
*
Expand Down
18 changes: 10 additions & 8 deletions src/rp2_common/hardware_vreg/vreg.c
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ void vreg_set_voltage(enum vreg_voltage voltage) {
VREG_AND_CHIP_RESET_VREG_VSEL_BITS
);

#elif PICO_RP2350
#else

hw_set_bits(&powman_hw->vreg_ctrl, POWMAN_PASSWORD_BITS | POWMAN_VREG_CTRL_UNLOCK_BITS);

Expand All @@ -32,19 +32,21 @@ void vreg_set_voltage(enum vreg_voltage voltage) {
while (powman_hw->vreg & POWMAN_VREG_UPDATE_IN_PROGRESS_BITS)
tight_loop_contents();

#endif
}

enum vreg_voltage vreg_get_voltage(void) {
#if PICO_RP2040
return (vreg_and_chip_reset_hw->vreg & VREG_AND_CHIP_RESET_VREG_VSEL_BITS) >> VREG_AND_CHIP_RESET_VREG_VSEL_LSB;
#else
panic_unsupported();
return (powman_hw->vreg & POWMAN_VREG_VSEL_BITS) >> POWMAN_VREG_VSEL_LSB;
#endif
}

void vreg_disable_voltage_limit(void) {
#if PICO_RP2040
// The voltage limit can't be disabled on RP2040 (was implemented by
// hardwiring the LDO controls)
return;
#elif PICO_RP2350
hw_set_bits(&powman_hw->vreg_ctrl, POWMAN_PASSWORD_BITS | POWMAN_VREG_CTRL_DISABLE_VOLTAGE_LIMIT_BITS);
// The voltage limit can't be disabled on RP2040 (was implemented by hard-wiring the LDO controls)
#else
panic_unsupported();
hw_set_bits(&powman_hw->vreg_ctrl, POWMAN_PASSWORD_BITS | POWMAN_VREG_CTRL_DISABLE_VOLTAGE_LIMIT_BITS);
#endif
}
2 changes: 2 additions & 0 deletions src/rp2_common/pico_runtime_init/BUILD.bazel
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,8 @@ cc_library(
"//src/rp2_common/hardware_base",
"//src/rp2_common/hardware_clocks",
"//src/rp2_common/hardware_ticks",
"//src/rp2_common/hardware_timer",
"//src/rp2_common/hardware_vreg",
"//src/rp2_common/pico_bootrom",
"//src/rp2_common/pico_runtime",
],
Expand Down
2 changes: 1 addition & 1 deletion src/rp2_common/pico_runtime_init/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ pico_mirrored_target_link_libraries(pico_runtime_init INTERFACE
)

if (TARGET hardware_clocks)
pico_mirrored_target_link_libraries(pico_runtime_init INTERFACE hardware_clocks)
pico_mirrored_target_link_libraries(pico_runtime_init INTERFACE hardware_clocks hardware_timer hardware_vreg)
endif()

# pico/runtime_init.h includes pico/runtime.h
Expand Down
11 changes: 11 additions & 0 deletions src/rp2_common/pico_runtime_init/runtime_init_clocks.c
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,8 @@
#include "hardware/clocks.h"
#include "hardware/pll.h"
#include "hardware/ticks.h"
#include "hardware/timer.h"
#include "hardware/vreg.h"
#include "hardware/xosc.h"
#if PICO_RP2040
#include "hardware/regs/rtc.h"
Expand Down Expand Up @@ -85,6 +87,15 @@ void __weak runtime_init_clocks(void) {
0,
XOSC_HZ);

// This must be done after we've configured CLK_REF to XOSC due to the need to time a delay
#if SYS_CLK_VREG_VOLTAGE_AUTO_ADJUST && defined(SYS_CLK_VREG_VOLTAGE_MIN)
if (vreg_get_voltage() < SYS_CLK_VREG_VOLTAGE_MIN) {
vreg_set_voltage(SYS_CLK_VREG_VOLTAGE_MIN);
// wait for voltage to settle; must use CPU cycles as TIMER is not yet clocked correctly
busy_wait_at_least_cycles((uint32_t)((SYS_CLK_VREG_VOLTAGE_AUTO_ADJUST_DELAY_US * (uint64_t)XOSC_HZ) / 1000000));
}
#endif

/// \tag::configure_clk_sys[]
// CLK SYS = PLL SYS (usually) 125MHz / 1 = 125MHz
clock_configure_undivided(clk_sys,
Expand Down

0 comments on commit c757f36

Please sign in to comment.