drivers/cavs_timer: Cleanup & simplification pass

General refactoring to clean up and futureproof this driver.

Remove false dependency on CONFIG_CAVS_ICTL.  This requires the CAVS
interrupt mask API, but doesn't touch the interrupt controller driver.

Remove a racy check for simultaneous interrupts.  This seems to have
been well intentioned, but it's needless: the spinlock around the
last_count computation guarantees that colliding interrupts will
correctly compute elapsed ticks (i.e. the last will compute and
announce zero ticks, which is correct and expected).  And this opened
a tiny window where you could incorrectly ignore a just-set timeout.

Factor out the specific registers used (there are only five) into
pointer-valued macros instead of banging them directly.

Unify interrupt initialization for main and auxiliary cores.

Signed-off-by: Andy Ross <andrew.j.ross@intel.com>
diff --git a/drivers/timer/Kconfig.cavs b/drivers/timer/Kconfig.cavs
index f5d4071..6733119 100644
--- a/drivers/timer/Kconfig.cavs
+++ b/drivers/timer/Kconfig.cavs
@@ -5,7 +5,6 @@
 
 config CAVS_TIMER
 	bool "CAVS DSP Wall Clock Timer on Intel SoC"
-	depends on CAVS_ICTL
 	select TICKLESS_CAPABLE
 	select TIMER_HAS_64BIT_CYCLE_COUNTER
 	help
diff --git a/drivers/timer/cavs_timer.c b/drivers/timer/cavs_timer.c
index 7ccb92b..f65c349 100644
--- a/drivers/timer/cavs_timer.c
+++ b/drivers/timer/cavs_timer.c
@@ -19,8 +19,10 @@
  * all available CPU cores and provides a synchronized timer under SMP.
  */
 
-#define TIMER		0
-#define TIMER_IRQ	DSP_WCT_IRQ(TIMER)
+#define COMPARATOR_IDX  0 /* 0 or 1 */
+
+#define TIMER_IRQ	DSP_WCT_IRQ(COMPARATOR_IDX)
+
 #define CYC_PER_TICK	(CONFIG_SYS_CLOCK_HW_CYCLES_PER_SEC	\
 			/ CONFIG_SYS_CLOCK_TICKS_PER_SEC)
 #define MAX_CYC		0xFFFFFFFFUL
@@ -28,7 +30,13 @@
 #define MIN_DELAY	(CONFIG_SYS_CLOCK_HW_CYCLES_PER_SEC / 100000)
 
 BUILD_ASSERT(MIN_DELAY < CYC_PER_TICK);
-BUILD_ASSERT(TIMER >= 0 && TIMER <= 1);
+BUILD_ASSERT(COMPARATOR_IDX >= 0 && COMPARATOR_IDX <= 1);
+
+#define WCTCS      (&CAVS_SHIM.dspwctcs)
+#define COUNTER_HI (&CAVS_SHIM.dspwc_hi)
+#define COUNTER_LO (&CAVS_SHIM.dspwc_lo)
+#define COMPARE_HI (&CAVS_SHIM.UTIL_CAT(UTIL_CAT(dspwct, COMPARATOR_IDX), c_hi))
+#define COMPARE_LO (&CAVS_SHIM.UTIL_CAT(UTIL_CAT(dspwct, COMPARATOR_IDX), c_lo))
 
 static struct k_spinlock lock;
 static uint64_t last_count;
@@ -36,18 +44,13 @@
 static void set_compare(uint64_t time)
 {
 	/* Disarm the comparator to prevent spurious triggers */
-	CAVS_SHIM.dspwctcs &= ~DSP_WCT_CS_TA(TIMER);
+	*WCTCS &= ~DSP_WCT_CS_TA(COMPARATOR_IDX);
 
-	if (TIMER == 0) {
-		CAVS_SHIM.dspwct0c_lo = (uint32_t)time;
-		CAVS_SHIM.dspwct0c_hi = (uint32_t)(time >> 32);
-	} else {
-		CAVS_SHIM.dspwct1c_lo = (uint32_t)time;
-		CAVS_SHIM.dspwct1c_hi = (uint32_t)(time >> 32);
-	}
+	*COMPARE_LO = (uint32_t)time;
+	*COMPARE_HI = (uint32_t)(time >> 32);
 
 	/* Arm the timer */
-	CAVS_SHIM.dspwctcs |= DSP_WCT_CS_TA(TIMER);
+	*WCTCS |= DSP_WCT_CS_TA(COMPARATOR_IDX);
 }
 
 static uint64_t count(void)
@@ -61,9 +64,9 @@
 	uint32_t hi0, hi1, lo;
 
 	do {
-		hi0 = CAVS_SHIM.dspwc_hi;
-		lo = CAVS_SHIM.dspwc_lo;
-		hi1 = CAVS_SHIM.dspwc_hi;
+		hi0 = *COUNTER_HI;
+		lo = *COUNTER_LO;
+		hi1 = *COUNTER_HI;
 	} while (hi0 != hi1);
 
 	return (((uint64_t)hi0) << 32) | lo;
@@ -71,7 +74,7 @@
 
 static uint32_t count32(void)
 {
-	return CAVS_SHIM.dspwc_lo;
+	return *COUNTER_LO;
 }
 
 static void compare_isr(const void *arg)
@@ -83,24 +86,10 @@
 	k_spinlock_key_t key = k_spin_lock(&lock);
 
 	curr = count();
-
-#ifdef CONFIG_SMP
-	/* If we are too soon since last_count,
-	 * this interrupt is likely the same interrupt
-	 * event but being processed by another CPU.
-	 * Since it has already been processed and
-	 * ticks announced, skip it.
-	 */
-	if ((count32() - (uint32_t)last_count) < MIN_DELAY) {
-		k_spin_unlock(&lock, key);
-		return;
-	}
-#endif
-
 	dticks = (uint32_t)((curr - last_count) / CYC_PER_TICK);
 
 	/* Clear the triggered bit */
-	CAVS_SHIM.dspwctcs |= DSP_WCT_CS_TT(TIMER);
+	*WCTCS |= DSP_WCT_CS_TT(COMPARATOR_IDX);
 
 	last_count += dticks * CYC_PER_TICK;
 
@@ -172,16 +161,22 @@
 	return count();
 }
 
-/* Runs on secondary cores */
+/* Interrupt setup is partially-cpu-local state, so needs to be
+ * repeated for each core when it starts.  Note that this conforms to
+ * the Zephyr convention of sending timer interrupts to all cpus (for
+ * the benefit of timeslicing).
+ */
+static void irq_init(void)
+{
+	int cpu = arch_curr_cpu()->id;
+
+	CAVS_INTCTRL[cpu].l2.clear = CAVS_L2_DWCT0;
+	irq_enable(TIMER_IRQ);
+}
+
 void smp_timer_init(void)
 {
-	/* This enables the Timer 0 (or 1) interrupt for CPU n.
-	 *
-	 * FIXME: Done in this way because we don't have an API
-	 * to enable interrupts per CPU.
-	 */
-	CAVS_INTCTRL[arch_curr_cpu()->id].l2.clear = CAVS_L2_DWCT0;
-	irq_enable(TIMER_IRQ);
+	irq_init();
 }
 
 /* Runs on core 0 only */
@@ -192,7 +187,7 @@
 	IRQ_CONNECT(TIMER_IRQ, 0, compare_isr, 0, 0);
 	set_compare(curr + CYC_PER_TICK);
 	last_count = curr;
-	irq_enable(TIMER_IRQ);
+	irq_init();
 	return 0;
 }