timer: intel_adsp: use DTS for hardware information

Convert timer driver to use a light weight syscon and DTS and convert
register information to use offsets and sys_read/sys_write instead of
structs.

Signed-off-by: Anas Nashif <anas.nashif@intel.com>
This commit is contained in:
Anas Nashif 2022-08-20 14:11:36 -04:00
commit 52297422fc
14 changed files with 150 additions and 68 deletions

View file

@ -13,6 +13,12 @@
#include <adsp_shim.h>
#include <adsp_interrupt.h>
#define DT_DRV_COMPAT intel_adsp_timer
#ifdef CONFIG_SOC_SERIES_INTEL_ACE
#include <ace_v1x-regs.h>
#endif
/**
* @file
* @brief Intel Audio DSP Wall Clock Timer driver
@ -39,16 +45,20 @@
BUILD_ASSERT(MIN_DELAY < CYC_PER_TICK);
BUILD_ASSERT(COMPARATOR_IDX >= 0 && COMPARATOR_IDX <= 1);
#define WCTCS (ADSP_SHIM_DSPWCTS)
#define COUNTER_HI (ADSP_SHIM_DSPWCH)
#define COUNTER_LO (ADSP_SHIM_DSPWCL)
#define COMPARE_HI (ADSP_SHIM_COMPARE_HI(COMPARATOR_IDX))
#define COMPARE_LO (ADSP_SHIM_COMPARE_LO(COMPARATOR_IDX))
#define DSP_WCT_CS_TT(x) BIT(4 + x)
static struct k_spinlock lock;
static uint64_t last_count;
/* Not using current syscon driver due to overhead due to MMU support */
#define SYSCON_REG_ADDR DT_REG_ADDR(DT_INST_PHANDLE(0, syscon))
#define DSPWCTCS_ADDR (SYSCON_REG_ADDR + ADSP_DSPWCTCS_OFFSET)
#define DSPWCT0C_LO_ADDR (SYSCON_REG_ADDR + ADSP_DSPWCT0C_OFFSET)
#define DSPWCT0C_HI_ADDR (SYSCON_REG_ADDR + ADSP_DSPWCT0C_OFFSET + 4)
#define DSPWC_LO_ADDR (SYSCON_REG_ADDR + ADSP_DSPWC_OFFSET)
#define DSPWC_HI_ADDR (SYSCON_REG_ADDR + ADSP_DSPWC_OFFSET + 4)
#if defined(CONFIG_TEST)
const int32_t z_sys_timer_irq_for_test = TIMER_IRQ; /* See tests/kernel/context */
#endif
@ -56,13 +66,15 @@ const int32_t z_sys_timer_irq_for_test = TIMER_IRQ; /* See tests/kernel/context
static void set_compare(uint64_t time)
{
/* Disarm the comparator to prevent spurious triggers */
*WCTCS &= ~DSP_WCT_CS_TA(COMPARATOR_IDX);
sys_write32(sys_read32(DSPWCTCS_ADDR) & (~DSP_WCT_CS_TA(COMPARATOR_IDX)),
SYSCON_REG_ADDR + ADSP_DSPWCTCS_OFFSET);
*COMPARE_LO = (uint32_t)time;
*COMPARE_HI = (uint32_t)(time >> 32);
sys_write32((uint32_t)time, DSPWCT0C_LO_ADDR);
sys_write32((uint32_t)(time >> 32), DSPWCT0C_HI_ADDR);
/* Arm the timer */
*WCTCS |= DSP_WCT_CS_TA(COMPARATOR_IDX);
sys_write32(sys_read32(DSPWCTCS_ADDR) | (DSP_WCT_CS_TA(COMPARATOR_IDX)),
DSPWCTCS_ADDR);
}
static uint64_t count(void)
@ -76,17 +88,19 @@ static uint64_t count(void)
uint32_t hi0, hi1, lo;
do {
hi0 = *COUNTER_HI;
lo = *COUNTER_LO;
hi1 = *COUNTER_HI;
hi0 = sys_read32(DSPWC_HI_ADDR);
lo = sys_read32(DSPWC_LO_ADDR);
hi1 = sys_read32(DSPWC_HI_ADDR);
} while (hi0 != hi1);
return (((uint64_t)hi0) << 32) | lo;
}
static uint32_t count32(void)
{
return *COUNTER_LO;
uint32_t counter_lo;
counter_lo = sys_read32(DSPWC_LO_ADDR);
return counter_lo;
}
static void compare_isr(const void *arg)
@ -101,7 +115,8 @@ static void compare_isr(const void *arg)
dticks = (curr - last_count) / CYC_PER_TICK;
/* Clear the triggered bit */
*WCTCS |= DSP_WCT_CS_TT(COMPARATOR_IDX);
sys_write32(sys_read32(DSPWCTCS_ADDR) | DSP_WCT_CS_TT(COMPARATOR_IDX),
DSPWCTCS_ADDR);
last_count += dticks * CYC_PER_TICK;
@ -188,7 +203,8 @@ static void irq_init(void)
*/
#ifdef CONFIG_SOC_SERIES_INTEL_ACE
ACE_DINT[cpu].ie[ACE_INTL_TTS] |= BIT(COMPARATOR_IDX + 1);
*WCTCS |= ADSP_SHIM_DSPWCTCS_TTIE(COMPARATOR_IDX);
sys_write32(sys_read32(DSPWCTCS_ADDR) | ADSP_SHIM_DSPWCTCS_TTIE(COMPARATOR_IDX),
DSPWCTCS_ADDR);
#else
CAVS_INTCTRL[cpu].l2.clear = CAVS_L2_DWCT0;
#endif