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
parent b81daae643
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

View File

@ -0,0 +1,21 @@
# Copyright (c) 2022 Intel Corp.
# SPDX-License-Identifier: Apache-2.0
description: Intel ADSP Timer
compatible: "intel,adsp-timer"
include: base.yaml
properties:
reg:
required: false
interrupts:
required: false
syscon:
type: phandle
required: true
description: |
phandle to syscon node.

View File

@ -147,6 +147,17 @@
reg = <0x71f00 0x100>;
};
tts: tts@72000 {
compatible = "intel,adsp-tts";
reg = <0x72000 0x70>;
status = "okay";
};
timer: timer {
compatible = "intel,adsp-timer";
syscon = <&tts>;
};
lps: lps@71ac0 {
compatible = "intel,adsp-lps";
reg = <0x00071ac0 0x100>;

View File

@ -101,6 +101,11 @@
read-only;
};
timer: timer {
compatible = "intel,adsp-timer";
syscon = <&shim>;
};
core_intc: core_intc@0 {
compatible = "cdns,xtensa-core-intc";
reg = <0x00 0x400>;

View File

@ -64,6 +64,10 @@
compatible = "intel,adsp-shim";
reg = <0x71f00 0x100>;
};
timer: timer {
compatible = "intel,adsp-timer";
syscon = <&shim>;
};
mem_window0: mem_window@71a00 {
compatible = "intel,adsp-mem-window";

View File

@ -92,6 +92,11 @@
read-only;
};
timer: timer {
compatible = "intel,adsp-timer";
syscon = <&shim>;
};
l2lm: l2lm@71d00 {
compatible = "intel,cavs-l2lm";
reg = <0x71d00 0x20>;

View File

@ -44,6 +44,10 @@
reg = <0x71f00 0x100>;
};
timer: timer {
compatible = "intel,adsp-timer";
syscon = <&shim>;
};
mem_window0: mem_window@71a00 {
compatible = "intel,adsp-mem-window";
@ -71,6 +75,7 @@
memory = <&sram0>;
read-only;
};
l2lm: l2lm@71d00 {
compatible = "intel,cavs-l2lm";
reg = <0x71d00 0x20>;

View File

@ -112,6 +112,11 @@
read-only;
};
timer: timer {
compatible = "intel,adsp-timer";
syscon = <&shim>;
};
sspbase: ssp_base@71c00 {
compatible = "intel,cavs-sspbase";
reg = <0x71C00 0x100>;

View File

@ -68,6 +68,11 @@
memory = <&sram0>;
};
timer: timer {
compatible = "intel,adsp-timer";
syscon = <&shim>;
};
l2lm: l2lm@71d00 {
compatible = "intel,cavs-l2lm";
reg = <0x71d00 0x20>;

View File

@ -52,37 +52,24 @@ struct cavs_shim {
#define CAVS_SHIM (*((volatile struct cavs_shim *)DT_REG_ADDR(DT_NODELABEL(shim))))
struct clk64 {
uint32_t lo;
uint32_t hi;
};
#define ADSP_TTSCAP_OFFSET 0x00
#define ADSP_RTCWC_OFFSET 0x08
#define ADSP_DSPWCCTL_OFFSET 0x10
#define ADSP_DSPWCSTS_OFFSET 0x12
#define ADSP_DSPWCAV_OFFSET 0x18
#define ADSP_DSPWC_OFFSET 0x20
#define ADSP_DSPWCTCS_OFFSET 0x28
#define ADSP_DSPWCT0C_OFFSET 0x30
#define ADSP_DSPWCT1C_OFFSET 0x38
#define ADSP_TSCTRL_OFFSET 0x40
#define ADSP_ISCS_OFFSET 0x44
#define ADSP_LSCS_OFFSET 0x48
#define ADSP_DWCCS_OFFSET 0x50
#define ADSP_ARTCS_OFFSET 0x58
#define ADSP_LWCCS_OFFSET 0x60
#define ADSP_CLTSYNC_OFFSET 0x70
/* Timers & Time Stamping register block */
struct adsp_tftts {
uint32_t ttscap;
uint32_t unused0;
struct clk64 rtcwc;
uint16_t wcctl;
uint16_t wcsts;
uint32_t unused1;
struct clk64 wcav;
struct clk64 wc;
uint32_t wctcs;
uint32_t unused2;
struct clk64 wctc[2];
};
/* These registers are for timers / time stamping usages under DSP FW management. */
#define ADSP_DFTTS_REG 0x72000
#define ADSP_DFTTS (*(volatile struct adsp_tftts *)ADSP_DFTTS_REG)
#define ADSP_SHIM_DSPWCTS (&ADSP_DFTTS.wctcs)
#define ADSP_SHIM_DSPWCH (&ADSP_DFTTS.wc.hi)
#define ADSP_SHIM_DSPWCL (&ADSP_DFTTS.wc.lo)
#define ADSP_SHIM_COMPARE_HI(idx) (&ADSP_DFTTS.wctc[idx].hi)
#define ADSP_SHIM_COMPARE_LO(idx) (&ADSP_DFTTS.wctc[idx].lo)
#define ADSP_SHIM_DSPWCTCS_TTIE(c) BIT(8 + (c))

View File

@ -55,14 +55,18 @@ struct cavs_shim {
#define CAVS_SHIM (*((volatile struct cavs_shim *)DT_REG_ADDR(DT_NODELABEL(shim))))
#define ADSP_SHIM_DSPWCTS (&CAVS_SHIM.dspwctcs)
#define ADSP_SHIM_DSPWCH (&CAVS_SHIM.dspwc_hi)
#define ADSP_SHIM_DSPWCL (&CAVS_SHIM.dspwc_lo)
#define ADSP_SHIM_COMPARE_HI(idx) (&CAVS_SHIM.UTIL_CAT(UTIL_CAT(dspwct, idx), c_hi))
#define ADSP_SHIM_COMPARE_LO(idx) (&CAVS_SHIM.UTIL_CAT(UTIL_CAT(dspwct, idx), c_lo))
#define ADSP_SHIM_DSPWCTCS_TTIE(c) BIT(8 + (c))
#define ADSP_DSPWC_OFFSET 0x20
#define ADSP_DSPWCTCS_OFFSET 0x28
#define ADSP_DSPWCT0C_OFFSET 0x30
#define ADSP_DSPWCT1C_OFFSET 0x38
#define ADSP_CLKCTL_OFFSET 0x78
#define ADSP_CLKSTS_OFFSET 0x7C
#define ADSP_PWRCTL_OFFSET 0x90
#define ADSP_PWRSTS_OFFSET 0x92
#define ADSP_LPSCTL_OFFSET 0x94
/* Host memory window control. Not strictly part of the shim block. */
struct cavs_win {
uint32_t dmwba;

View File

@ -53,11 +53,16 @@ struct cavs_shim {
#define CAVS_SHIM (*((volatile struct cavs_shim *)DT_REG_ADDR(DT_NODELABEL(shim))))
#define ADSP_SHIM_DSPWCTS (&CAVS_SHIM.dspwctcs)
#define ADSP_SHIM_DSPWCH (&CAVS_SHIM.dspwc_hi)
#define ADSP_SHIM_DSPWCL (&CAVS_SHIM.dspwc_lo)
#define ADSP_SHIM_COMPARE_HI(idx) (&CAVS_SHIM.UTIL_CAT(UTIL_CAT(dspwct, idx), c_hi))
#define ADSP_SHIM_COMPARE_LO(idx) (&CAVS_SHIM.UTIL_CAT(UTIL_CAT(dspwct, idx), c_lo))
#define ADSP_DSPWC_OFFSET 0x20
#define ADSP_DSPWCTCS_OFFSET 0x28
#define ADSP_DSPWCT0C_OFFSET 0x30
#define ADSP_DSPWCT1C_OFFSET 0x38
#define ADSP_CLKCTL_OFFSET 0x78
#define ADSP_CLKSTS_OFFSET 0x7C
#define ADSP_PWRCTL_OFFSET 0x90
#define ADSP_PWRSTS_OFFSET 0x92
#define ADSP_LPSCTL_OFFSET 0x94
#define ADSP_SHIM_DSPWCTCS_TTIE(c) BIT(8 + (c))

View File

@ -53,14 +53,19 @@ struct cavs_shim {
#define CAVS_SHIM (*((volatile struct cavs_shim *)DT_REG_ADDR(DT_NODELABEL(shim))))
#define ADSP_SHIM_DSPWCTS (&CAVS_SHIM.dspwctcs)
#define ADSP_SHIM_DSPWCH (&CAVS_SHIM.dspwc_hi)
#define ADSP_SHIM_DSPWCL (&CAVS_SHIM.dspwc_lo)
#define ADSP_SHIM_COMPARE_HI(idx) (&CAVS_SHIM.UTIL_CAT(UTIL_CAT(dspwct, idx), c_hi))
#define ADSP_SHIM_COMPARE_LO(idx) (&CAVS_SHIM.UTIL_CAT(UTIL_CAT(dspwct, idx), c_lo))
#define ADSP_SHIM_DSPWCTCS_TTIE(c) BIT(8 + (c))
#define ADSP_DSPWC_OFFSET 0x20
#define ADSP_DSPWCTCS_OFFSET 0x28
#define ADSP_DSPWCT0C_OFFSET 0x30
#define ADSP_DSPWCT1C_OFFSET 0x38
#define ADSP_CLKCTL_OFFSET 0x78
#define ADSP_CLKSTS_OFFSET 0x7C
#define ADSP_PWRCTL_OFFSET 0x90
#define ADSP_PWRSTS_OFFSET 0x92
#define ADSP_LPSCTL_OFFSET 0x94
/* L2 Local Memory control (cAVS 1.8+) */
struct cavs_l2lm {
uint32_t l2lmcap;

View File

@ -53,14 +53,18 @@ struct cavs_shim {
#define CAVS_SHIM (*((volatile struct cavs_shim *)DT_REG_ADDR(DT_NODELABEL(shim))))
#define ADSP_SHIM_DSPWCTS (&CAVS_SHIM.dspwctcs)
#define ADSP_SHIM_DSPWCH (&CAVS_SHIM.dspwc_hi)
#define ADSP_SHIM_DSPWCL (&CAVS_SHIM.dspwc_lo)
#define ADSP_SHIM_COMPARE_HI(idx) (&CAVS_SHIM.UTIL_CAT(UTIL_CAT(dspwct, idx), c_hi))
#define ADSP_SHIM_COMPARE_LO(idx) (&CAVS_SHIM.UTIL_CAT(UTIL_CAT(dspwct, idx), c_lo))
#define ADSP_SHIM_DSPWCTCS_TTIE(c) BIT(8 + (c))
#define ADSP_DSPWC_OFFSET 0x20
#define ADSP_DSPWCTCS_OFFSET 0x28
#define ADSP_DSPWCT0C_OFFSET 0x30
#define ADSP_DSPWCT1C_OFFSET 0x38
#define ADSP_CLKCTL_OFFSET 0x78
#define ADSP_CLKSTS_OFFSET 0x7C
#define ADSP_PWRCTL_OFFSET 0x90
#define ADSP_PWRSTS_OFFSET 0x92
#define ADSP_LPSCTL_OFFSET 0x94
/* L2 Local Memory control (cAVS 1.8+) */
struct cavs_l2lm {
uint32_t l2lmcap;