blob: 7c95b89f22e12d2672206eacb41461b3b43b34dd [file] [log] [blame]
#!/usr/bin/env python3
#
# Copyright (c) 2019 Intel Corporation
#
# SPDX-License-Identifier: Apache-2.0
import time
import logging
from ctypes import c_uint16, addressof
from lib.driver import DiagDriver, Register
import lib.registers as regs_def
import lib.platforms as plat_def
class Device:
def __init__(self):
self.__opened = False
self.drv = DiagDriver()
self.dev_info = None
self.hda_bar_mmap = None
self.dsp_bar_mmap = None
self.hda_gctl = None
self.hda_gcap = None
self.hda_ppctl = None
self.hda_spibe = None
self.dsp_ctl_sts = None
self.dsp_hipci = None
self.dsp_hipcie = None
self.dsp_hipct = None
self.fw_status = None
self.fw_err_code = None
self.ipc_len = None
self.ipc_cmd = None
self.allocated = []
def close(self):
if not self.__opened:
logging.warning("Audio device not opened!!!")
return
self.__opened = False
def open_device(self):
logging.debug(">>> Device.open_device()")
# Open device to get HDA BAR and DSP BAR
self.dev_info = self.drv.open_device()
# HDA MMAP
self.hda_bar_mmap = self.drv.mmap(self.dev_info.hda_bar.base_p,
self.dev_info.hda_bar.size)
self.dev_info.hda_bar.base_v = addressof(self.hda_bar_mmap)
# DSP MMAP
self.dsp_bar_mmap = self.drv.mmap(self.dev_info.dsp_bar.base_p,
self.dev_info.dsp_bar.size)
self.dev_info.dsp_bar.base_v = addressof(self.dsp_bar_mmap)
logging.debug(self.dev_info)
# Registers from HDA
self.hda_gctl = Register(self.hda_bar_mmap,
regs_def.HDA_GR_GCTL)
self.hda_gcap = Register(self.hda_bar_mmap,
regs_def.HDA_GR_GCAP, c_uint16)
self.hda_ppctl = Register(self.hda_bar_mmap,
regs_def.HDA_PPC_PPCTL)
self.hda_spibe = Register(self.hda_bar_mmap,
regs_def.HDA_SPBF_SPBFCTL)
# Registers from DSP
self.dsp_ctl_sts = Register(self.dsp_bar_mmap,
regs_def.ADSP_GR_ADSPCS)
self.dsp_hipci = Register(self.dsp_bar_mmap,
regs_def.ADSP_IPC_HIPCI)
self.dsp_hipcie = Register(self.dsp_bar_mmap,
regs_def.ADSP_IPC_HIPCIE)
self.dsp_hipct = Register(self.dsp_bar_mmap,
regs_def.ADSP_IPC_HIPCT)
self.fw_status = Register(self.dsp_bar_mmap,
plat_def.FW_STATUS)
self.fw_err_code = Register(self.dsp_bar_mmap,
plat_def.FW_ERR_CODE)
self.ipc_len = Register(self.dsp_bar_mmap,
plat_def.FW_MBOX_UPLINK + plat_def.IPC_GLOBAL_LEN)
self.ipc_cmd = Register(self.dsp_bar_mmap,
plat_def.FW_MBOX_UPLINK + plat_def.IPC_GLOBAL_CMD)
self.__opened = True
logging.debug("<<< Device.open_device()")
def alloc_memory(self, size):
logging.debug(">>> Device.alloc_memory()")
buf = self.drv.alloc_mem(size)
if buf.dma_addr_p == 0:
raise RuntimeError("Could not allocate the memory")
self.allocated.append(buf)
logging.debug("<<< Device.alloc_memory()")
return buf
def free_memory(self, mem):
logging.debug(">>> Device.free_memory()")
if mem in self.allocated:
ret = self.drv.free_mem(mem)
if ret != 0:
logging.error("Failed to free memory")
self.allocated.remove(mem)
else:
logging.warning("Cannot find the memory from list")
logging.debug("<<< Device.free_memory()")
def power_cycle(self):
logging.debug("Controller power down")
self.hda_gctl.value = 0
while self.hda_gctl.value != 0:
time.sleep(0.1)
logging.debug(" HDA_GCTL=%s" % self.hda_gctl)
logging.debug("Controller power up")
self.hda_gctl.value = 1
while self.hda_gctl.value != 1:
time.sleep(0.1)
logging.debug(" HDA_GCTL=%s" % self.hda_gctl)
def enable_proc_pipe_ctl(self):
logging.debug("Enable processing pipe control")
iss = ((self.hda_gcap.value & regs_def.HDA_GR_GCAP_ISS)
>> regs_def.HDA_GR_GCAP_ISS_OFFSET)
oss = ((self.hda_gcap.value & regs_def.HDA_GR_GCAP_OSS)
>> regs_def.HDA_GR_GCAP_OSS_OFFSET)
iss_mask = int("1" * iss, 2)
oss_mask = int("1" * oss, 2)
dma_mask = iss_mask + (oss_mask << iss)
# Enable processing pipe
self.hda_ppctl.value = self.hda_ppctl.value | 0x40000000 | dma_mask
logging.debug(" HDA_PPCTL=%s" % self.hda_ppctl)
def get_ipc_message(self):
logging.info("Read IPC message from DSP")
logging.info("IPC LEN: %s" % self.ipc_len)
logging.info("IPC CMD: %s" % self.ipc_cmd)
def core_reset_enter(self, core_mask):
# Set Reset Bit for cores
logging.debug("Enter core reset(mask=0x%08X)" % core_mask)
reset = core_mask << regs_def.ADSP_GR_ADSPCS_CRST_OFFSET
self._update_bits(self.dsp_ctl_sts, reset, reset)
# Check core entered reset
reg = self.dsp_ctl_sts.value
if (reg & reset) != reset:
raise RuntimeError("Reset enter failed: DSP_CTL_STS=%s core_maks=0x%08X"
% (self.dsp_ctl_sts, core_mask))
logging.debug(" DSP_CTL_STS=%s" % self.dsp_ctl_sts)
def core_reset_leave(self, core_mask):
# Set Reset Bit for cores
logging.debug("Leave core reset(mask=0x%08X)" % core_mask)
leave = core_mask << regs_def.ADSP_GR_ADSPCS_CRST_OFFSET
self._update_bits(self.dsp_ctl_sts, leave, 0)
# Check core entered reset
reg = self.dsp_ctl_sts.value
if (reg & leave) != 0:
raise RuntimeError("Reset leave failed: DSP_CTL_STS=%s core_maks=0x%08X"
% (self.dsp_ctl_sts, core_mask))
logging.debug(" DSP_CTL_STS=%s" % self.dsp_ctl_sts)
def core_stall_reset(self, core_mask):
logging.debug("Stall core(mask=0x%08X)" % core_mask)
stall = core_mask << regs_def.ADSP_GR_ADSPCS_CSTALL_OFFSET
self._update_bits(self.dsp_ctl_sts, stall, stall)
logging.debug(" DSP_CTL_STS=%s" % self.dsp_ctl_sts)
self.core_reset_enter(core_mask)
def core_run(self, core_mask):
self.core_reset_leave(core_mask)
logging.debug("Run/Unstall core(mask=0x%08X)" % core_mask)
run = core_mask << regs_def.ADSP_GR_ADSPCS_CSTALL_OFFSET
self._update_bits(self.dsp_ctl_sts, run, 0)
logging.debug(" DSP_CTL_STS=%s" % self.dsp_ctl_sts)
def core_power_down(self, core_mask):
logging.debug("Power down core(mask=0x%08X)" % core_mask)
mask = core_mask << regs_def.ADSP_GR_ADSPCS_SPA_OFFSET
self._update_bits(self.dsp_ctl_sts, mask, 0)
cnt = 0
while cnt < 10:
cpa = self.dsp_ctl_sts.value & regs_def.ADSP_GR_ADSPCS_CPA
mask = (core_mask & 0) << regs_def.ADSP_GR_ADSPCS_CPA_OFFSET
if cpa == mask:
logging.debug("Confirmed match value: 0x%04X" % cpa)
break
time.sleep(0.01)
cnt += 1
if cnt == 10:
logging.error(" DSP_CTL_STS=%s" % self.dsp_ctl_sts)
raise RuntimeError("Failed to power down the core")
logging.debug(" DSP_CTL_STS=%s" % self.dsp_ctl_sts)
def core_power_up(self, core_mask):
logging.debug("Power Up core(mask=0x%08X)" % core_mask)
mask = core_mask << regs_def.ADSP_GR_ADSPCS_SPA_OFFSET
self._update_bits(self.dsp_ctl_sts, mask, mask)
cnt = 0
while cnt < 10:
cpa = self.dsp_ctl_sts.value & regs_def.ADSP_GR_ADSPCS_CPA
mask = core_mask << regs_def.ADSP_GR_ADSPCS_CPA_OFFSET
if cpa == mask:
logging.debug("Confirmed match value: 0x%04X" % cpa)
break
time.sleep(0.01)
cnt += 1
if cnt == 10:
logging.error(" DSP_CTL_STS=%s" % self.dsp_ctl_sts)
raise RuntimeError("Failed to power up the core")
logging.debug(" DSP_CTL_STS=%s" % self.dsp_ctl_sts)
@staticmethod
def _update_bits(reg, mask, value):
old_val = reg.value
new_val = (old_val & ~mask) | (value & mask)
if old_val == new_val:
return False
reg.value = new_val
return True