tests/intel_adsp: MP core power fixups for older cAVS platforms
On cAVS before 2.5, core power was controlled by the host. Add a command to the cavstool.py script to allow us to do that under test command so we can exercise multiprocessor startup/shutdown outside of SOF. Signed-off-by: Andy Ross <andrew.j.ross@intel.com>
This commit is contained in:
parent
438219c466
commit
45242d9214
4 changed files with 42 additions and 2 deletions
|
@ -101,6 +101,11 @@ extern bool soc_cpus_active[CONFIG_MP_NUM_CPUS];
|
|||
* responsibility. This function will hang if the other CPU fails to
|
||||
* reach idle.
|
||||
*
|
||||
* @note On older cAVS hardware, core power is controlled by the host.
|
||||
* This function must still be called for OS bookeeping, but it is
|
||||
* insufficient without application coordination (and careful
|
||||
* synchronization!) with the host x86 environment.
|
||||
*
|
||||
* @param id CPU to halt, not current cpu or cpu 0
|
||||
* @return 0 on success, -EINVAL on error
|
||||
*/
|
||||
|
|
|
@ -202,8 +202,13 @@ int soc_adsp_halt_cpu(int id)
|
|||
CAVS_SHIM.pwrctl &= ~CAVS_PWRCTL_TCPDSPPG(id);
|
||||
CAVS_SHIM.clkctl &= ~CAVS_CLKCTL_TCPLCG(id);
|
||||
|
||||
/* Wait for the CPU to reach an idle state before returing */
|
||||
while (CAVS_SHIM.pwrsts & CAVS_PWRSTS_PDSPPGS(id)) {
|
||||
/* If possible, wait for the other CPU to reach an idle state
|
||||
* before returning. On older hardware this doesn't work
|
||||
* because power is controlled by the host, so synchronization
|
||||
* needs to be part of the application layer.
|
||||
*/
|
||||
while (IS_ENABLED(CONFIG_SOC_SERIES_INTEL_CAVS_V25) &&
|
||||
(CAVS_SHIM.pwrsts & CAVS_PWRSTS_PDSPPGS(id))) {
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
|
|
@ -336,6 +336,8 @@ def ipc_command(data, ext_data):
|
|||
asyncio.ensure_future(ipc_delay_done())
|
||||
elif data == 2: # echo back ext_data as a message command
|
||||
send_msg = True
|
||||
elif data == 3: # set ADSPCS
|
||||
dsp.ADSPCS = ext_data
|
||||
else:
|
||||
log.warning(f"cavstool: Unrecognized IPC command 0x{data:x} ext 0x{ext_data:x}")
|
||||
|
||||
|
|
|
@ -4,6 +4,7 @@
|
|||
#include <stdlib.h>
|
||||
#include <kernel.h>
|
||||
#include <ztest.h>
|
||||
#include <cavs_ipc.h>
|
||||
#include "tests.h"
|
||||
|
||||
#define RUN_ON_STACKSZ 2048
|
||||
|
@ -148,14 +149,41 @@ void halt_and_restart(int cpu)
|
|||
{
|
||||
printk("halt/restart core %d...\n", cpu);
|
||||
static bool alive_flag;
|
||||
uint32_t all_cpus = BIT(CONFIG_MP_NUM_CPUS) - 1;
|
||||
|
||||
/* On older hardware we need to get the host to turn the core
|
||||
* off. Construct an ADSPCS with only this core disabled
|
||||
*/
|
||||
if (!IS_ENABLED(CONFIG_SOC_SERIES_INTEL_CAVS_V25)) {
|
||||
cavs_ipc_send_message(CAVS_HOST_DEV, IPCCMD_ADSPCS,
|
||||
(all_cpus & ~BIT(cpu)) << 16);
|
||||
}
|
||||
|
||||
soc_adsp_halt_cpu(cpu);
|
||||
|
||||
alive_flag = false;
|
||||
run_on_cpu(cpu, alive_fn, &alive_flag, false);
|
||||
k_msleep(100);
|
||||
zassert_false(alive_flag, "cpu didn't halt");
|
||||
|
||||
if (!IS_ENABLED(CONFIG_SOC_SERIES_INTEL_CAVS_V25)) {
|
||||
/* Likewise need to ask the host to turn it back on,
|
||||
* and give it some time to spin up before we hit it.
|
||||
* We don't have a return message wired to be notified
|
||||
* of completion.
|
||||
*/
|
||||
cavs_ipc_send_message(CAVS_HOST_DEV, IPCCMD_ADSPCS,
|
||||
all_cpus << 16);
|
||||
k_msleep(50);
|
||||
}
|
||||
|
||||
z_smp_start_cpu(cpu);
|
||||
|
||||
if (!IS_ENABLED(CONFIG_SOC_SERIES_INTEL_CAVS_V25)) {
|
||||
/* And... startup is slow on old platforms too */
|
||||
k_msleep(50);
|
||||
}
|
||||
|
||||
WAIT_FOR(alive_flag == true);
|
||||
|
||||
k_thread_abort(&run_on_threads[cpu]);
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue