Skip to content

Fix powman powman_configure_wakeup_state and powman_get_power_state #2516

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 2 commits into
base: develop
Choose a base branch
from
Open
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
31 changes: 21 additions & 10 deletions src/rp2_common/hardware_powman/powman.c
Original file line number Diff line number Diff line change
Expand Up @@ -125,7 +125,7 @@ void powman_timer_disable_gpio_1hz_sync(void) {
}

powman_power_state powman_get_power_state(void) {
uint32_t state_reg = powman_hw->state & POWMAN_STATE_CURRENT_BITS;
uint32_t state_reg = ~powman_hw->state & POWMAN_STATE_CURRENT_BITS;
// todo we should have hardware/regs/powman.h values for these
static_assert(POWMAN_POWER_DOMAIN_SRAM_BANK1 == 0, "");
static_assert(POWMAN_POWER_DOMAIN_SRAM_BANK0 == 1, "");
Expand Down Expand Up @@ -181,19 +181,30 @@ int powman_set_power_state(powman_power_state state) {
}

bool powman_configure_wakeup_state(powman_power_state sleep_state, powman_power_state wakeup_state) {
// When powman wakes up it can keep the state of the sram0 and sram1 banks. Note, it can't
// explicitly
bool valid = powman_power_state_is_domain_on(wakeup_state, POWMAN_POWER_DOMAIN_XIP_CACHE);
// Must be entering a P1 low-power state (SWCORE OFF).
bool valid = !powman_power_state_is_domain_on(sleep_state, POWMAN_POWER_DOMAIN_SWITCHED_CORE);
// Must be waking up in a P0 state (SWCORE ON).
valid &= powman_power_state_is_domain_on(wakeup_state, POWMAN_POWER_DOMAIN_SWITCHED_CORE);
valid &= powman_power_state_is_domain_on(sleep_state, POWMAN_POWER_DOMAIN_SRAM_BANK0) ==
powman_power_state_is_domain_on(wakeup_state, POWMAN_POWER_DOMAIN_SRAM_BANK0);
valid &= powman_power_state_is_domain_on(sleep_state, POWMAN_POWER_DOMAIN_SRAM_BANK1) ==
powman_power_state_is_domain_on(wakeup_state, POWMAN_POWER_DOMAIN_SRAM_BANK1);
powman_power_state current_state = powman_get_power_state();
bool current_sram0 = powman_power_state_is_domain_on(current_state, POWMAN_POWER_DOMAIN_SRAM_BANK0);
bool current_sram1 = powman_power_state_is_domain_on(current_state, POWMAN_POWER_DOMAIN_SRAM_BANK1);
bool sleep_sram0 = powman_power_state_is_domain_on(sleep_state, POWMAN_POWER_DOMAIN_SRAM_BANK0);
bool sleep_sram1 = powman_power_state_is_domain_on(sleep_state, POWMAN_POWER_DOMAIN_SRAM_BANK1);
bool wakeup_sram0 = powman_power_state_is_domain_on(wakeup_state, POWMAN_POWER_DOMAIN_SRAM_BANK0);
bool wakeup_sram1 = powman_power_state_is_domain_on(wakeup_state, POWMAN_POWER_DOMAIN_SRAM_BANK1);
// Sleep state cannot turn ON SRAM0 or SRAM1 if it is OFF in the current state.
if (!current_sram0) valid &= !sleep_sram0;
if (!current_sram1) valid &= !sleep_sram1;
// Wakeup state cannot turn OFF SRAM0 or SRAM1 if it is ON in the sleep state.
if (sleep_sram0) valid &= wakeup_sram0;
if (sleep_sram1) valid &= wakeup_sram1;
if (valid) {
// Prepare power sequencer to power SRAM domains on wakeup.
powman_clear_bits(&powman_hw->seq_cfg, POWMAN_SEQ_CFG_HW_PWRUP_SRAM0_BITS | POWMAN_SEQ_CFG_HW_PWRUP_SRAM1_BITS);
uint32_t seq_cfg_set = 0;
if (!powman_power_state_is_domain_on(sleep_state, POWMAN_POWER_DOMAIN_SRAM_BANK0)) seq_cfg_set |= POWMAN_SEQ_CFG_HW_PWRUP_SRAM0_BITS;
if (!powman_power_state_is_domain_on(sleep_state, POWMAN_POWER_DOMAIN_SRAM_BANK1)) seq_cfg_set |= POWMAN_SEQ_CFG_HW_PWRUP_SRAM1_BITS;
// Sequencer SRAM power transitions from sleep to wakeup are: OFF->ON (0), ON->ON (1) and OFF->OFF (1)
if (sleep_sram0 == wakeup_sram0) seq_cfg_set |= POWMAN_SEQ_CFG_HW_PWRUP_SRAM0_BITS;
if (sleep_sram1 == wakeup_sram1) seq_cfg_set |= POWMAN_SEQ_CFG_HW_PWRUP_SRAM1_BITS;
powman_set_bits(&powman_hw->seq_cfg, seq_cfg_set);
}
return valid;
Expand Down