intel-adsp/ace: pm: Only core 0 can d0i3

Secondary cores are not allowed to be power gated on
runtime-idle. They have to explicitely set off by host command.

Remove this state from secondary CPUs so power management logic
does not need workarounds to enforce this behavior.

Signed-off-by: Flavio Ceolin <flavio.ceolin@intel.com>
This commit is contained in:
Flavio Ceolin 2024-02-19 15:10:42 -08:00 committed by Maureen Helm
commit 301055dec0
2 changed files with 11 additions and 22 deletions

View file

@ -25,14 +25,14 @@
device_type = "cpu"; device_type = "cpu";
compatible = "cdns,tensilica-xtensa-lx7"; compatible = "cdns,tensilica-xtensa-lx7";
reg = <1>; reg = <1>;
cpu-power-states = <&d0i3 &d3>; cpu-power-states = <&d3>;
}; };
cpu2: cpu@2 { cpu2: cpu@2 {
device_type = "cpu"; device_type = "cpu";
compatible = "cdns,tensilica-xtensa-lx7"; compatible = "cdns,tensilica-xtensa-lx7";
reg = <2>; reg = <2>;
cpu-power-states = <&d0i3 &d3>; cpu-power-states = <&d3>;
}; };
power-states { power-states {

View file

@ -266,6 +266,7 @@ void pm_state_set(enum pm_state state, uint8_t substate_id)
{ {
ARG_UNUSED(substate_id); ARG_UNUSED(substate_id);
uint32_t cpu = arch_proc_id(); uint32_t cpu = arch_proc_id();
uint32_t battr;
int ret; int ret;
ARG_UNUSED(ret); ARG_UNUSED(ret);
@ -340,19 +341,20 @@ void pm_state_set(enum pm_state state, uint8_t substate_id)
power_gate_entry(cpu); power_gate_entry(cpu);
} }
break; break;
/* Only core 0 handles this state */
case PM_STATE_RUNTIME_IDLE: case PM_STATE_RUNTIME_IDLE:
battr = DSPCS.bootctl[cpu].battr & (~LPSCTL_BATTR_MASK);
DSPCS.bootctl[cpu].bctl &= ~DSPBR_BCTL_WAITIPPG; DSPCS.bootctl[cpu].bctl &= ~DSPBR_BCTL_WAITIPPG;
DSPCS.bootctl[cpu].bctl &= ~DSPBR_BCTL_WAITIPCG; DSPCS.bootctl[cpu].bctl &= ~DSPBR_BCTL_WAITIPCG;
soc_cpu_power_down(cpu); soc_cpu_power_down(cpu);
if (cpu == 0) { battr |= (DSPBR_BATTR_LPSCTL_RESTORE_BOOT & LPSCTL_BATTR_MASK);
uint32_t battr = DSPCS.bootctl[cpu].battr & (~LPSCTL_BATTR_MASK); DSPCS.bootctl[cpu].battr = battr;
battr |= (DSPBR_BATTR_LPSCTL_RESTORE_BOOT & LPSCTL_BATTR_MASK);
DSPCS.bootctl[cpu].battr = battr;
}
ret = pm_device_runtime_put(INTEL_ADSP_HST_DOMAIN_DEV); ret = pm_device_runtime_put(INTEL_ADSP_HST_DOMAIN_DEV);
__ASSERT_NO_MSG(ret == 0); __ASSERT_NO_MSG(ret == 0);
power_gate_entry(cpu); power_gate_entry(cpu);
break; break;
default: default:
@ -395,17 +397,6 @@ void pm_state_exit_post_ops(enum pm_state state, uint8_t substate_id)
soc_cpus_active[cpu] = true; soc_cpus_active[cpu] = true;
sys_cache_data_flush_and_invd_all(); sys_cache_data_flush_and_invd_all();
} else if (state == PM_STATE_RUNTIME_IDLE) { } else if (state == PM_STATE_RUNTIME_IDLE) {
if (cpu != 0) {
/* NOTE: HW should support dynamic power gating on secondary cores.
* But since there is no real profit from it, functionality is not
* fully implemented.
* SOF PM policy will not allowed primary core to enter d0i3 state
* when secondary cores are active.
*/
__ASSERT(false, "state not supported on secondary core");
return;
}
soc_cpu_power_up(cpu); soc_cpu_power_up(cpu);
if (!WAIT_FOR(soc_cpu_is_powered(cpu), if (!WAIT_FOR(soc_cpu_is_powered(cpu),
@ -418,9 +409,7 @@ void pm_state_exit_post_ops(enum pm_state state, uint8_t substate_id)
#else #else
DSPCS.bootctl[cpu].bctl |= DSPBR_BCTL_WAITIPCG | DSPBR_BCTL_WAITIPPG; DSPCS.bootctl[cpu].bctl |= DSPBR_BCTL_WAITIPCG | DSPBR_BCTL_WAITIPPG;
#endif /* CONFIG_ADSP_IDLE_CLOCK_GATING */ #endif /* CONFIG_ADSP_IDLE_CLOCK_GATING */
if (cpu == 0) { DSPCS.bootctl[cpu].battr &= (~LPSCTL_BATTR_MASK);
DSPCS.bootctl[cpu].battr &= (~LPSCTL_BATTR_MASK);
}
soc_cpus_active[cpu] = true; soc_cpus_active[cpu] = true;
sys_cache_data_flush_and_invd_all(); sys_cache_data_flush_and_invd_all();