soc: intel_adsp: enable DfTTS-based time stamping on ACE platforms
This patch enables time stamping controlled by DSP Timers / Time Stamping logic on ACE1.5 / ACE2.0 platforms. Signed-off-by: Tomasz Lissowski <tomasz.lissowski@intel.com>
This commit is contained in:
parent
83b7513937
commit
042cb6ac4e
5 changed files with 148 additions and 0 deletions
|
@ -11,6 +11,7 @@ zephyr_library_sources(
|
|||
power_down.S
|
||||
power.c
|
||||
boot.c
|
||||
timestamp.c
|
||||
)
|
||||
|
||||
zephyr_include_directories(include)
|
||||
|
|
29
soc/xtensa/intel_adsp/ace/include/adsp_timestamp.h
Normal file
29
soc/xtensa/intel_adsp/ace/include/adsp_timestamp.h
Normal file
|
@ -0,0 +1,29 @@
|
|||
/*
|
||||
* Copyright (c) 2023 Intel Corporation
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
#ifndef ZEPHYR_SOC_INTEL_ADSP_ACE_TIMESTAMP_H_
|
||||
#define ZEPHYR_SOC_INTEL_ADSP_ACE_TIMESTAMP_H_
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
/* Captured timestamp data - contains a copy of all DfTTS snapshot registers. */
|
||||
struct intel_adsp_timestamp {
|
||||
uint32_t iscs; /* copy of DfISCS register */
|
||||
uint64_t lscs; /* copy of DfLSCS register */
|
||||
uint64_t dwccs; /* copy of DfDWCCS register */
|
||||
uint64_t artcs; /* copy of DfARTCS register */
|
||||
uint32_t lwccs; /* copy of DfLWCCS register */
|
||||
};
|
||||
|
||||
/*
|
||||
* @brief Perform timestamping process using DfTTS logic.
|
||||
*
|
||||
* @param tsctrl Value to be applied to DfTSCTRL register to control timestamping logic
|
||||
* @param timestamp Captured timestamp data
|
||||
*/
|
||||
int intel_adsp_get_timestamp(uint32_t tsctrl, struct intel_adsp_timestamp *timestamp);
|
||||
|
||||
#endif /* ZEPHYR_SOC_INTEL_ADSP_ACE_TIMESTAMP_H_ */
|
|
@ -8,6 +8,8 @@
|
|||
|
||||
#ifndef _ASMLANGUAGE
|
||||
|
||||
#include <zephyr/sys/util.h>
|
||||
|
||||
/**
|
||||
* DfPMCCH
|
||||
* Power Management / Clock Control (HST) Registers
|
||||
|
@ -138,6 +140,15 @@ struct ace_dfpmccu {
|
|||
|
||||
#define ADSP_SHIM_DSPWCTCS_TTIE(c) BIT(8 + (c))
|
||||
|
||||
#define ADSP_SHIM_TSCTRL_NTK BIT(31)
|
||||
#define ADSP_SHIM_TSCTRL_IONTE BIT(30)
|
||||
#define ADSP_SHIM_TSCTRL_DMATS GENMASK(13, 12)
|
||||
#define ADSP_SHIM_TSCTRL_CLNKS GENMASK(11, 10)
|
||||
#define ADSP_SHIM_TSCTRL_HHTSE BIT(7)
|
||||
#define ADSP_SHIM_TSCTRL_LWCS BIT(6)
|
||||
#define ADSP_SHIM_TSCTRL_ODTS BIT(5)
|
||||
#define ADSP_SHIM_TSCTRL_CDMAS GENMASK(4, 0)
|
||||
|
||||
#endif /* _ASMLANGUAGE */
|
||||
|
||||
#define ACE_CLKCTL_WOVCRO BIT(21) /* Request WOVCRO clock */
|
||||
|
|
|
@ -8,6 +8,8 @@
|
|||
|
||||
#ifndef _ASMLANGUAGE
|
||||
|
||||
#include <zephyr/sys/util.h>
|
||||
|
||||
/**
|
||||
* DfPMCCH
|
||||
* Power Management / Clock Control (HST) Registers
|
||||
|
@ -138,6 +140,15 @@ struct ace_dfpmccu {
|
|||
|
||||
#define ADSP_SHIM_DSPWCTCS_TTIE(c) BIT(8 + (c))
|
||||
|
||||
#define ADSP_SHIM_TSCTRL_NTK BIT(31)
|
||||
#define ADSP_SHIM_TSCTRL_IONTE BIT(30)
|
||||
#define ADSP_SHIM_TSCTRL_DMATS GENMASK(13, 12)
|
||||
#define ADSP_SHIM_TSCTRL_CLNKS GENMASK(11, 10)
|
||||
#define ADSP_SHIM_TSCTRL_HHTSE BIT(7)
|
||||
#define ADSP_SHIM_TSCTRL_LWCS BIT(6)
|
||||
#define ADSP_SHIM_TSCTRL_ODTS BIT(5)
|
||||
#define ADSP_SHIM_TSCTRL_CDMAS GENMASK(4, 0)
|
||||
|
||||
#endif /* _ASMLANGUAGE */
|
||||
|
||||
#define ACE_CLKCTL_WOVCRO BIT(4) /* Request WOVCRO clock */
|
||||
|
|
96
soc/xtensa/intel_adsp/ace/timestamp.c
Normal file
96
soc/xtensa/intel_adsp/ace/timestamp.c
Normal file
|
@ -0,0 +1,96 @@
|
|||
/*
|
||||
* Copyright (c) 2023 Intel Corporation
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
#include <stdint.h>
|
||||
#include <zephyr/spinlock.h>
|
||||
#include <zephyr/devicetree.h>
|
||||
#include <adsp_shim.h>
|
||||
#include <adsp_timestamp.h>
|
||||
|
||||
#define TTS_BASE_ADDR DT_REG_ADDR(DT_NODELABEL(tts))
|
||||
|
||||
#define TSCTRL_ADDR (TTS_BASE_ADDR + ADSP_TSCTRL_OFFSET)
|
||||
#define ISCS_ADDR (TTS_BASE_ADDR + ADSP_ISCS_OFFSET)
|
||||
#define LSCS_ADDR (TTS_BASE_ADDR + ADSP_LSCS_OFFSET)
|
||||
#define DWCCS_ADDR (TTS_BASE_ADDR + ADSP_DWCCS_OFFSET)
|
||||
#define ARTCS_ADDR (TTS_BASE_ADDR + ADSP_ARTCS_OFFSET)
|
||||
#define LWCCS_ADDR (TTS_BASE_ADDR + ADSP_LWCCS_OFFSET)
|
||||
|
||||
/* Copies the bit-field specified by mask from src to dest */
|
||||
#define BITS_COPY(dest, src, mask) ((dest) = ((dest) & ~(mask)) | ((src) & (mask)))
|
||||
|
||||
static struct k_spinlock lock;
|
||||
|
||||
int intel_adsp_get_timestamp(uint32_t tsctrl, struct intel_adsp_timestamp *timestamp)
|
||||
{
|
||||
uint32_t trigger_mask = ADSP_SHIM_TSCTRL_HHTSE | ADSP_SHIM_TSCTRL_ODTS;
|
||||
uint32_t trigger_bits = tsctrl & trigger_mask;
|
||||
uint32_t tsctrl_temp;
|
||||
k_spinlock_key_t key;
|
||||
int ret = 0;
|
||||
|
||||
/* Exactly one trigger bit must be set in a valid request */
|
||||
if (POPCOUNT(trigger_bits) != 1) {
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
key = k_spin_lock(&lock);
|
||||
|
||||
tsctrl_temp = sys_read32(TSCTRL_ADDR);
|
||||
|
||||
/* Abort if any timestamp capture in progress */
|
||||
if (tsctrl_temp & trigger_mask) {
|
||||
ret = -EBUSY;
|
||||
goto out;
|
||||
}
|
||||
|
||||
/* Clear NTK (RW/1C) bit if needed */
|
||||
if (tsctrl_temp & ADSP_SHIM_TSCTRL_NTK) {
|
||||
sys_write32(tsctrl_temp, TSCTRL_ADDR);
|
||||
tsctrl_temp &= ~ADSP_SHIM_TSCTRL_NTK;
|
||||
}
|
||||
|
||||
/* Setup the timestamping logic according to request */
|
||||
BITS_COPY(tsctrl_temp, tsctrl, ADSP_SHIM_TSCTRL_IONTE);
|
||||
BITS_COPY(tsctrl_temp, tsctrl, ADSP_SHIM_TSCTRL_DMATS);
|
||||
BITS_COPY(tsctrl_temp, tsctrl, ADSP_SHIM_TSCTRL_CLNKS);
|
||||
BITS_COPY(tsctrl_temp, tsctrl, ADSP_SHIM_TSCTRL_LWCS);
|
||||
BITS_COPY(tsctrl_temp, tsctrl, ADSP_SHIM_TSCTRL_CDMAS);
|
||||
sys_write32(tsctrl_temp, TSCTRL_ADDR);
|
||||
|
||||
/* Start new timestamp capture by setting one of mutually exclusive
|
||||
* trigger bits.
|
||||
*/
|
||||
tsctrl_temp |= trigger_bits;
|
||||
sys_write32(tsctrl_temp, TSCTRL_ADDR);
|
||||
|
||||
/* Wait for timestamp capture to complete */
|
||||
while (1) {
|
||||
tsctrl_temp = sys_read32(TSCTRL_ADDR);
|
||||
if (tsctrl_temp & ADSP_SHIM_TSCTRL_NTK) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/* Copy the timestamp data from HW registers to the snapshot buffer
|
||||
* provided by caller. As NTK bit is high at this stage, the timestamp
|
||||
* data in HW is guaranteed to be valid and static.
|
||||
*/
|
||||
timestamp->iscs = sys_read32(ISCS_ADDR);
|
||||
timestamp->lscs = sys_read64(LSCS_ADDR);
|
||||
timestamp->dwccs = sys_read64(DWCCS_ADDR);
|
||||
timestamp->artcs = sys_read64(ARTCS_ADDR);
|
||||
timestamp->lwccs = sys_read32(LWCCS_ADDR);
|
||||
|
||||
/* Clear NTK (RW/1C) bit */
|
||||
tsctrl_temp |= ADSP_SHIM_TSCTRL_NTK;
|
||||
sys_write32(tsctrl_temp, TSCTRL_ADDR);
|
||||
|
||||
out:
|
||||
k_spin_unlock(&lock, key);
|
||||
|
||||
return ret;
|
||||
}
|
Loading…
Add table
Add a link
Reference in a new issue