@@ -125,7 +125,7 @@ void powman_timer_disable_gpio_1hz_sync(void) {
125
125
}
126
126
127
127
powman_power_state powman_get_power_state (void ) {
128
- uint32_t state_reg = powman_hw -> state & POWMAN_STATE_CURRENT_BITS ;
128
+ uint32_t state_reg = ~ powman_hw -> state & POWMAN_STATE_CURRENT_BITS ;
129
129
// todo we should have hardware/regs/powman.h values for these
130
130
static_assert (POWMAN_POWER_DOMAIN_SRAM_BANK1 == 0 , "" );
131
131
static_assert (POWMAN_POWER_DOMAIN_SRAM_BANK0 == 1 , "" );
@@ -181,19 +181,30 @@ int powman_set_power_state(powman_power_state state) {
181
181
}
182
182
183
183
bool powman_configure_wakeup_state (powman_power_state sleep_state , powman_power_state wakeup_state ) {
184
- // When powman wakes up it can keep the state of the sram0 and sram1 banks. Note, it can't
185
- // explicitly
186
- bool valid = powman_power_state_is_domain_on ( wakeup_state , POWMAN_POWER_DOMAIN_XIP_CACHE );
184
+ // Must be entering a P1 low-power state (SWCORE OFF).
185
+ bool valid = ! powman_power_state_is_domain_on ( sleep_state , POWMAN_POWER_DOMAIN_SWITCHED_CORE );
186
+ // Must be waking up in a P0 state (SWCORE ON).
187
187
valid &= powman_power_state_is_domain_on (wakeup_state , POWMAN_POWER_DOMAIN_SWITCHED_CORE );
188
- valid &= powman_power_state_is_domain_on (sleep_state , POWMAN_POWER_DOMAIN_SRAM_BANK0 ) ==
189
- powman_power_state_is_domain_on (wakeup_state , POWMAN_POWER_DOMAIN_SRAM_BANK0 );
190
- valid &= powman_power_state_is_domain_on (sleep_state , POWMAN_POWER_DOMAIN_SRAM_BANK1 ) ==
191
- powman_power_state_is_domain_on (wakeup_state , POWMAN_POWER_DOMAIN_SRAM_BANK1 );
188
+ powman_power_state current_state = powman_get_power_state ();
189
+ bool current_sram0 = powman_power_state_is_domain_on (current_state , POWMAN_POWER_DOMAIN_SRAM_BANK0 );
190
+ bool current_sram1 = powman_power_state_is_domain_on (current_state , POWMAN_POWER_DOMAIN_SRAM_BANK1 );
191
+ bool sleep_sram0 = powman_power_state_is_domain_on (sleep_state , POWMAN_POWER_DOMAIN_SRAM_BANK0 );
192
+ bool sleep_sram1 = powman_power_state_is_domain_on (sleep_state , POWMAN_POWER_DOMAIN_SRAM_BANK1 );
193
+ bool wakeup_sram0 = powman_power_state_is_domain_on (wakeup_state , POWMAN_POWER_DOMAIN_SRAM_BANK0 );
194
+ bool wakeup_sram1 = powman_power_state_is_domain_on (wakeup_state , POWMAN_POWER_DOMAIN_SRAM_BANK1 );
195
+ // Sleep state cannot turn ON SRAM0 or SRAM1 if it is OFF in the current state.
196
+ if (!current_sram0 ) valid &= !sleep_sram0 ;
197
+ if (!current_sram1 ) valid &= !sleep_sram1 ;
198
+ // Wakeup state cannot turn OFF SRAM0 or SRAM1 if it is ON in the sleep state.
199
+ if (sleep_sram0 ) valid &= wakeup_sram0 ;
200
+ if (sleep_sram1 ) valid &= wakeup_sram1 ;
192
201
if (valid ) {
202
+ // Prepare power sequencer to power SRAM domains on wakeup.
193
203
powman_clear_bits (& powman_hw -> seq_cfg , POWMAN_SEQ_CFG_HW_PWRUP_SRAM0_BITS | POWMAN_SEQ_CFG_HW_PWRUP_SRAM1_BITS );
194
204
uint32_t seq_cfg_set = 0 ;
195
- if (!powman_power_state_is_domain_on (sleep_state , POWMAN_POWER_DOMAIN_SRAM_BANK0 )) seq_cfg_set |= POWMAN_SEQ_CFG_HW_PWRUP_SRAM0_BITS ;
196
- if (!powman_power_state_is_domain_on (sleep_state , POWMAN_POWER_DOMAIN_SRAM_BANK1 )) seq_cfg_set |= POWMAN_SEQ_CFG_HW_PWRUP_SRAM1_BITS ;
205
+ // Sequencer SRAM power transitions from sleep to wakeup are: OFF->ON (0), ON->ON (1) and OFF->OFF (1)
206
+ if (sleep_sram0 == wakeup_sram0 ) seq_cfg_set |= POWMAN_SEQ_CFG_HW_PWRUP_SRAM0_BITS ;
207
+ if (sleep_sram1 == wakeup_sram1 ) seq_cfg_set |= POWMAN_SEQ_CFG_HW_PWRUP_SRAM1_BITS ;
197
208
powman_set_bits (& powman_hw -> seq_cfg , seq_cfg_set );
198
209
}
199
210
return valid ;
0 commit comments