soc/intel_adsp: Fixups for cavs18 SMP boot
This platform was stale for a long time and got a little left behind. Basic OS stuff was working but secondary core bringup didn't. It has a slightly different set of choices from the "weird hardware quirks" menu: + Like cAVS 1.5, it boots from a ROM that needs a short delay after power-up before it can receive the startup IDC. + But, like 2.5 and unlike 1.5, it doesn't start running until the PWRCTL bit for the core gets set by DSP software (1.5 gets launched by the host). So the delay needed to move down a bit. + It wants that PWRCTL bit to be set last, after CLKCTL enables the clock. (Which makes sense I guess: EE classes always tell you hold circuits in reset while an initial clock propagates). Not sure why it was in the reverse order originally; this way works for everything. + The ROM likes to scribble on the interrupt controller and mask its own IDC interrupts after we've already set it up. They have to be unmasked. We had code to do this already, thinking it was a workaround for legecy SOF code (that we never actually located). Now I'm thinking it was this behavior all along being detected by SOF's more extensive hardware CI. Take out the test and do it always, it's like nine instructions. + The host/loader-side behavior is a mix of 1.5 and 2.5. It won't actually start the secondary cores under host command, but it does need to see bits set for them in ADSPCS for the DSP-initiated power-up to work (2.5 would just ignore all but core 0's bits). + Also, like 1.5, it needs the host DMA stream to be explicitly stopped (and not just reset) or else further loads will be unstable. Note that the loader changes now require more logic than just "1.5 or not", so the platform detection has been enhanced to fully categorize the device based on PCI ID (not quite: we don't have any 2.0 platform hardware, so I left that alone for now). Signed-off-by: Andy Ross <andrew.j.ross@intel.com>
This commit is contained in:
parent
1a7bc06086
commit
dbff5861c4
2 changed files with 33 additions and 33 deletions
|
@ -27,7 +27,12 @@ def map_regs():
|
|||
p = runx(f"grep -iPl 'PCI_CLASS=40(10|38)0' /sys/bus/pci/devices/*/uevent")
|
||||
pcidir = os.path.dirname(p)
|
||||
|
||||
cavs15 = open(f"{pcidir}/device").read().rstrip() in [ "0x5a98", "0x1a98", "0x3198" ]
|
||||
# Platform/quirk detection. ID lists cribbed from the SOF kernel driver
|
||||
global cavs15, cavs18, cavs25
|
||||
did = int(open(f"{pcidir}/device").read().rstrip(), 16)
|
||||
cavs15 = did in [ 0x5a98, 0x1a98, 0x3198 ]
|
||||
cavs18 = did in [ 0x9dc8, 0xa348, 0x02c8, 0x06c8, 0xa3f0 ]
|
||||
cavs25 = did in [ 0xa0c8, 0x43c8, 0x4b55, 0x4b58, 0x7ad0, 0x51c8 ]
|
||||
|
||||
# Check sysfs for a loaded driver and remove it
|
||||
if os.path.exists(f"{pcidir}/driver"):
|
||||
|
@ -77,7 +82,7 @@ def map_regs():
|
|||
dsp.SRAM_FW_STATUS = 0x80000 # Start of first SRAM window
|
||||
dsp.freeze()
|
||||
|
||||
return (hda, sd, dsp, hda_ostream_id, cavs15)
|
||||
return (hda, sd, dsp, hda_ostream_id)
|
||||
|
||||
def setup_dma_mem(fw_bytes):
|
||||
(mem, phys_addr) = map_phys_mem()
|
||||
|
@ -210,10 +215,12 @@ def load_firmware(fw_file):
|
|||
hda.SPBFCTL |= (1 << hda_ostream_id)
|
||||
hda.SD_SPIB = len(fw_bytes)
|
||||
|
||||
# Start DSP. Just core 0 on 1.8+ (secondary core startup is handled
|
||||
# internally), but on 1.5 the host controls the power levers.
|
||||
# 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.
|
||||
log.info(f"Starting DSP, ADSPCS = 0x{dsp.ADSPCS:x}")
|
||||
dsp.ADSPCS = 0xff0000 if cavs15 else 0x01fefe
|
||||
dsp.ADSPCS = 0xff0000 if not cavs25 else 0x01fefe
|
||||
while (dsp.ADSPCS & 0x1000000) == 0: pass
|
||||
|
||||
# Wait for the ROM to boot and signal it's ready. This short
|
||||
|
@ -248,10 +255,11 @@ def load_firmware(fw_file):
|
|||
if not alive:
|
||||
log.warning(f"Load failed? FW_STATUS = 0x{dsp.SRAM_FW_STATUS:x}")
|
||||
|
||||
# Turn DMA off and reset the stream. Clearing START first is a noop
|
||||
# per the spec, but required for 1.5, and makes the load on 1.8
|
||||
# unstable. Go figure.
|
||||
if cavs15:
|
||||
# Turn DMA off and reset the stream. Clearing START first is a
|
||||
# noop per the spec, but required for early versions (apparently
|
||||
# the reset doesn't stop the stream and the next load fails), and
|
||||
# makes the load on 2.5 unstable. Go figure.
|
||||
if not cavs25:
|
||||
sd.CTL &= ~2 # clear START
|
||||
sd.CTL |= 1
|
||||
log.info(f"cAVS firmware load complete")
|
||||
|
@ -288,9 +296,9 @@ def winstream_read(last_seq):
|
|||
return (seq, result.decode("utf-8"))
|
||||
|
||||
async def main():
|
||||
global hda, sd, dsp, hda_ostream_id, cavs15
|
||||
global hda, sd, dsp, hda_ostream_id
|
||||
try:
|
||||
(hda, sd, dsp, hda_ostream_id, cavs15) = map_regs()
|
||||
(hda, sd, dsp, hda_ostream_id) = map_regs()
|
||||
except Exception:
|
||||
log.error("Could not map device in sysfs; run as root.")
|
||||
sys.exit(1)
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue