From 3209bc1a4a803cb3e6a67cd0aa407e6259fd496d Mon Sep 17 00:00:00 2001 From: Ederson de Souza Date: Wed, 18 May 2022 12:09:10 -0700 Subject: [PATCH] soc/xtensa/intel_adsp/tools: Make cavstool.py DSP resetting more stable When using more than one core on cavs25, some hangs were made "persistent", as it seems not all cores were being properly reset, thus compromising tests - if a test hangs for any reason, subsequent tests that were not restrict to a single CPU would also fail. This patch mitigates these issues by two changes: - Closely mimics SOF Linux driver way of loading the firmware. So, explicit stall and reset (and "unstall" and "unreset") of cores, with appropriate checks that states have been reached; - More generous sleep before resetting the stream. Also, the status of ADSPCS (Audio DSP Control and Status) register is logged more thoroughly to aid debugging in case new issues arise. Signed-off-by: Ederson de Souza --- soc/xtensa/intel_adsp/tools/cavstool.py | 48 +++++++++++++++----- tests/boards/intel_adsp/hda/src/dma.c | 2 +- tests/boards/intel_adsp/hda/src/smoke.c | 2 +- tests/boards/intel_adsp/hda_log/src/logger.c | 2 +- 4 files changed, 40 insertions(+), 14 deletions(-) diff --git a/soc/xtensa/intel_adsp/tools/cavstool.py b/soc/xtensa/intel_adsp/tools/cavstool.py index 959203ab0c..d0c659b910 100755 --- a/soc/xtensa/intel_adsp/tools/cavstool.py +++ b/soc/xtensa/intel_adsp/tools/cavstool.py @@ -46,6 +46,12 @@ OUTBOX_OFFSET = (512 + (0 * 128)) * 1024 + 4096 INBOX_OFFSET = (512 + (1 * 128)) * 1024 WINSTREAM_OFFSET = (512 + (3 * 128)) * 1024 +# ADSPCS bits +CRST = 0 +CSTALL = 8 +SPA = 16 +CPA = 24 + class HDAStream: # creates an hda stream with at 2 buffers of buf_len def __init__(self, stream_id: int): @@ -355,6 +361,14 @@ class Regs: def runx(cmd): return subprocess.check_output(cmd, shell=True).decode().rstrip() +def mask(bit): + if cavs25: + return 0b1 << bit + if cavs18: + return 0b1111 << bit + if cavs15: + return 0b11 << bit + def load_firmware(fw_file): try: fw_bytes = open(fw_file, "rb").read() @@ -377,9 +391,14 @@ def load_firmware(fw_file): hda.GCTL = 1 while not hda.GCTL & 1: pass - log.info("Powering down DSP cores") - dsp.ADSPCS = 0xffff - while dsp.ADSPCS & 0xff000000: pass + log.info(f"Stalling and Resetting DSP cores, ADSPCS = 0x{dsp.ADSPCS:x}") + dsp.ADSPCS |= mask(CSTALL) + dsp.ADSPCS |= mask(CRST) + while (dsp.ADSPCS & mask(CRST)) == 0: pass + + log.info(f"Powering down DSP cores, ADSPCS = 0x{dsp.ADSPCS:x}") + dsp.ADSPCS &= ~mask(SPA) + while dsp.ADSPCS & mask(CPA): pass log.info(f"Configuring HDA stream {hda_ostream_id} to transfer firmware image") (buf_list_addr, num_bufs) = setup_dma_mem(fw_bytes) @@ -403,18 +422,25 @@ def load_firmware(fw_file): # Start DSP. Host needs to provide power to all cores on 1.5 # (which also starts them) and 1.8 (merely gates power, DSP also - # has to set PWRCTL). The bits for cores other than 0 are ignored - # on 2.5 where the DSP has full control. + # has to set PWRCTL). On 2.5 where the DSP has full control, + # and only core 0 is set. log.info(f"Starting DSP, ADSPCS = 0x{dsp.ADSPCS:x}") - dsp.ADSPCS = 0xff0000 if not cavs25 else 0x01fefe - while (dsp.ADSPCS & 0x1000000) == 0: pass + dsp.ADSPCS = mask(SPA) + while (dsp.ADSPCS & mask(CPA)) == 0: pass - # Wait for the ROM to boot and signal it's ready. This short + log.info(f"Unresetting DSP cores, ADSPCS = 0x{dsp.ADSPCS:x}") + dsp.ADSPCS &= ~mask(CRST) + while (dsp.ADSPCS & 1) != 0: pass + + log.info(f"Running DSP cores, ADSPCS = 0x{dsp.ADSPCS:x}") + dsp.ADSPCS &= ~mask(CSTALL) + + # Wait for the ROM to boot and signal it's ready. This not so short # sleep seems to be needed; if we're banging on the memory window # during initial boot (before/while the window control registers # are configured?) the DSP hardware will hang fairly reliably. - log.info("Wait for ROM startup") - time.sleep(0.1) + log.info(f"Wait for ROM startup, ADSPCS = 0x{dsp.ADSPCS:x}") + time.sleep(1) while (dsp.SRAM_FW_STATUS >> 24) != 5: pass # Send the DSP an IPC message to tell the device how to boot. @@ -443,7 +469,7 @@ def load_firmware(fw_file): # chromebook) putting the two writes next each other also hangs # the DSP! sd.CTL &= ~2 # clear START - time.sleep(0.1) + time.sleep(1) sd.CTL |= 1 log.info(f"cAVS firmware load complete") diff --git a/tests/boards/intel_adsp/hda/src/dma.c b/tests/boards/intel_adsp/hda/src/dma.c index 8b02997f4c..fe92ff6394 100644 --- a/tests/boards/intel_adsp/hda/src/dma.c +++ b/tests/boards/intel_adsp/hda/src/dma.c @@ -9,7 +9,7 @@ #include #include "tests.h" -#define IPC_TIMEOUT K_MSEC(500) +#define IPC_TIMEOUT K_MSEC(1500) #define DMA_BUF_SIZE 256 #define TRANSFER_SIZE 256 #define TRANSFER_COUNT 8 diff --git a/tests/boards/intel_adsp/hda/src/smoke.c b/tests/boards/intel_adsp/hda/src/smoke.c index adcd0a1a9b..2f367204b6 100644 --- a/tests/boards/intel_adsp/hda/src/smoke.c +++ b/tests/boards/intel_adsp/hda/src/smoke.c @@ -15,7 +15,7 @@ #define HDA_REGBLOCK_SIZE DT_PROP_BY_IDX(DT_NODELABEL(hda_host_out), reg, 1) #include -#define IPC_TIMEOUT K_MSEC(500) +#define IPC_TIMEOUT K_MSEC(1500) #define STREAM_ID 3U #define HDA_BUF_SIZE 256 #define TRANSFER_COUNT 8 diff --git a/tests/boards/intel_adsp/hda_log/src/logger.c b/tests/boards/intel_adsp/hda_log/src/logger.c index a0c01d1dd1..4ce389b528 100644 --- a/tests/boards/intel_adsp/hda_log/src/logger.c +++ b/tests/boards/intel_adsp/hda_log/src/logger.c @@ -17,7 +17,7 @@ #include LOG_MODULE_REGISTER(hda_test, LOG_LEVEL_DBG); -#define IPC_TIMEOUT K_MSEC(500) +#define IPC_TIMEOUT K_MSEC(1500) void hda_log_hook(uint32_t written) {