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 <ederson.desouza@intel.com>
This commit is contained in:
parent
f875d027a0
commit
3209bc1a4a
|
@ -46,6 +46,12 @@ OUTBOX_OFFSET = (512 + (0 * 128)) * 1024 + 4096
|
||||||
INBOX_OFFSET = (512 + (1 * 128)) * 1024
|
INBOX_OFFSET = (512 + (1 * 128)) * 1024
|
||||||
WINSTREAM_OFFSET = (512 + (3 * 128)) * 1024
|
WINSTREAM_OFFSET = (512 + (3 * 128)) * 1024
|
||||||
|
|
||||||
|
# ADSPCS bits
|
||||||
|
CRST = 0
|
||||||
|
CSTALL = 8
|
||||||
|
SPA = 16
|
||||||
|
CPA = 24
|
||||||
|
|
||||||
class HDAStream:
|
class HDAStream:
|
||||||
# creates an hda stream with at 2 buffers of buf_len
|
# creates an hda stream with at 2 buffers of buf_len
|
||||||
def __init__(self, stream_id: int):
|
def __init__(self, stream_id: int):
|
||||||
|
@ -355,6 +361,14 @@ class Regs:
|
||||||
def runx(cmd):
|
def runx(cmd):
|
||||||
return subprocess.check_output(cmd, shell=True).decode().rstrip()
|
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):
|
def load_firmware(fw_file):
|
||||||
try:
|
try:
|
||||||
fw_bytes = open(fw_file, "rb").read()
|
fw_bytes = open(fw_file, "rb").read()
|
||||||
|
@ -377,9 +391,14 @@ def load_firmware(fw_file):
|
||||||
hda.GCTL = 1
|
hda.GCTL = 1
|
||||||
while not hda.GCTL & 1: pass
|
while not hda.GCTL & 1: pass
|
||||||
|
|
||||||
log.info("Powering down DSP cores")
|
log.info(f"Stalling and Resetting DSP cores, ADSPCS = 0x{dsp.ADSPCS:x}")
|
||||||
dsp.ADSPCS = 0xffff
|
dsp.ADSPCS |= mask(CSTALL)
|
||||||
while dsp.ADSPCS & 0xff000000: pass
|
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")
|
log.info(f"Configuring HDA stream {hda_ostream_id} to transfer firmware image")
|
||||||
(buf_list_addr, num_bufs) = setup_dma_mem(fw_bytes)
|
(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
|
# 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
|
# (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
|
# has to set PWRCTL). On 2.5 where the DSP has full control,
|
||||||
# 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}")
|
log.info(f"Starting DSP, ADSPCS = 0x{dsp.ADSPCS:x}")
|
||||||
dsp.ADSPCS = 0xff0000 if not cavs25 else 0x01fefe
|
dsp.ADSPCS = mask(SPA)
|
||||||
while (dsp.ADSPCS & 0x1000000) == 0: pass
|
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
|
# sleep seems to be needed; if we're banging on the memory window
|
||||||
# during initial boot (before/while the window control registers
|
# during initial boot (before/while the window control registers
|
||||||
# are configured?) the DSP hardware will hang fairly reliably.
|
# are configured?) the DSP hardware will hang fairly reliably.
|
||||||
log.info("Wait for ROM startup")
|
log.info(f"Wait for ROM startup, ADSPCS = 0x{dsp.ADSPCS:x}")
|
||||||
time.sleep(0.1)
|
time.sleep(1)
|
||||||
while (dsp.SRAM_FW_STATUS >> 24) != 5: pass
|
while (dsp.SRAM_FW_STATUS >> 24) != 5: pass
|
||||||
|
|
||||||
# Send the DSP an IPC message to tell the device how to boot.
|
# 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
|
# chromebook) putting the two writes next each other also hangs
|
||||||
# the DSP!
|
# the DSP!
|
||||||
sd.CTL &= ~2 # clear START
|
sd.CTL &= ~2 # clear START
|
||||||
time.sleep(0.1)
|
time.sleep(1)
|
||||||
sd.CTL |= 1
|
sd.CTL |= 1
|
||||||
log.info(f"cAVS firmware load complete")
|
log.info(f"cAVS firmware load complete")
|
||||||
|
|
||||||
|
|
|
@ -9,7 +9,7 @@
|
||||||
#include <zephyr/drivers/dma.h>
|
#include <zephyr/drivers/dma.h>
|
||||||
#include "tests.h"
|
#include "tests.h"
|
||||||
|
|
||||||
#define IPC_TIMEOUT K_MSEC(500)
|
#define IPC_TIMEOUT K_MSEC(1500)
|
||||||
#define DMA_BUF_SIZE 256
|
#define DMA_BUF_SIZE 256
|
||||||
#define TRANSFER_SIZE 256
|
#define TRANSFER_SIZE 256
|
||||||
#define TRANSFER_COUNT 8
|
#define TRANSFER_COUNT 8
|
||||||
|
|
|
@ -15,7 +15,7 @@
|
||||||
#define HDA_REGBLOCK_SIZE DT_PROP_BY_IDX(DT_NODELABEL(hda_host_out), reg, 1)
|
#define HDA_REGBLOCK_SIZE DT_PROP_BY_IDX(DT_NODELABEL(hda_host_out), reg, 1)
|
||||||
#include <cavs_hda.h>
|
#include <cavs_hda.h>
|
||||||
|
|
||||||
#define IPC_TIMEOUT K_MSEC(500)
|
#define IPC_TIMEOUT K_MSEC(1500)
|
||||||
#define STREAM_ID 3U
|
#define STREAM_ID 3U
|
||||||
#define HDA_BUF_SIZE 256
|
#define HDA_BUF_SIZE 256
|
||||||
#define TRANSFER_COUNT 8
|
#define TRANSFER_COUNT 8
|
||||||
|
|
|
@ -17,7 +17,7 @@
|
||||||
#include <zephyr/logging/log.h>
|
#include <zephyr/logging/log.h>
|
||||||
LOG_MODULE_REGISTER(hda_test, LOG_LEVEL_DBG);
|
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)
|
void hda_log_hook(uint32_t written)
|
||||||
{
|
{
|
||||||
|
|
Loading…
Reference in a new issue