summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--board/cr50/board.h3
-rw-r--r--chip/g/hwtimer.c4
-rw-r--r--chip/npcx/hwtimer.c22
-rw-r--r--common/timer.c4
-rw-r--r--include/config.h3
-rw-r--r--include/timer.h2
6 files changed, 25 insertions, 13 deletions
diff --git a/board/cr50/board.h b/board/cr50/board.h
index 9a2f79717b..e2640dfd29 100644
--- a/board/cr50/board.h
+++ b/board/cr50/board.h
@@ -139,9 +139,6 @@
#define CONFIG_DCRYPTO
#define CONFIG_UPTO_SHA512
-/* Implement custom udelay, due to usec hwtimer imprecision. */
-#define CONFIG_HW_SPECIFIC_UDELAY
-
#define CONFIG_TPM_LOGGING
#ifndef __ASSEMBLER__
diff --git a/chip/g/hwtimer.c b/chip/g/hwtimer.c
index 91dba78c40..267cf395cf 100644
--- a/chip/g/hwtimer.c
+++ b/chip/g/hwtimer.c
@@ -178,14 +178,13 @@ int __hw_clock_source_init(uint32_t start_t)
return GC_IRQNUM_TIMELS0_TIMINT1;
}
-#ifdef CONFIG_HW_SPECIFIC_UDELAY
/*
* Custom chip/g udelay(), guaranteed to delay for at least us microseconds.
*
* Lost time during timer wrap is not taken into account since interrupt latency
* and __hw_clock_source_irq() execution time likely exceeds the lost 3us.
*/
-void udelay(unsigned us)
+__override void udelay(unsigned us)
{
unsigned t0 = __hw_clock_source_read();
@@ -210,4 +209,3 @@ void udelay(unsigned us)
while (__hw_clock_source_read() - t0 <= us)
;
}
-#endif /* CONFIG_HW_SPECIFIC_UDELAY */
diff --git a/chip/npcx/hwtimer.c b/chip/npcx/hwtimer.c
index e46a56fb1e..d9a5728942 100644
--- a/chip/npcx/hwtimer.c
+++ b/chip/npcx/hwtimer.c
@@ -16,6 +16,7 @@
#include "console.h"
#include "task.h"
#include "timer.h"
+#include "registers.h"
#include "util.h"
/* Depth of event timer */
@@ -332,3 +333,24 @@ int __hw_clock_source_init(uint32_t start_t)
return NPCX_IRQ_ITIM32;
}
+
+/*
+ * Unrolled udelay. It preserves LR, which points to the root cause of WD crash.
+ */
+__override void udelay(unsigned us)
+{
+ uint32_t cnt, cnt2;
+ unsigned t0;
+
+ cnt = NPCX_ITCNT32;
+ while ((cnt2 = NPCX_ITCNT32) != cnt)
+ cnt = cnt2;
+
+ t0 = TICK_ITIM32_MAX_CNT - cnt;
+
+ do {
+ cnt = NPCX_ITCNT32;
+ while ((cnt2 = NPCX_ITCNT32) != cnt)
+ cnt = cnt2;
+ } while (TICK_ITIM32_MAX_CNT - cnt - t0 <= us);
+}
diff --git a/common/timer.c b/common/timer.c
index 117cea4b71..6f31d93b09 100644
--- a/common/timer.c
+++ b/common/timer.c
@@ -94,8 +94,7 @@ void process_timers(int overflow)
} while (next.val <= get_time().val);
}
-#ifndef CONFIG_HW_SPECIFIC_UDELAY
-void udelay(unsigned us)
+__overridable void udelay(unsigned us)
{
unsigned t0 = __hw_clock_source_read();
@@ -112,7 +111,6 @@ void udelay(unsigned us)
while (__hw_clock_source_read() - t0 <= us)
;
}
-#endif
int timer_arm(timestamp_t tstamp, task_id_t tskid)
{
diff --git a/include/config.h b/include/config.h
index 443f93d738..86c1707512 100644
--- a/include/config.h
+++ b/include/config.h
@@ -1850,9 +1850,6 @@
*/
#undef CONFIG_HIBERNATE_PSL
-/* Use a hardware specific udelay(). */
-#undef CONFIG_HW_SPECIFIC_UDELAY
-
/*****************************************************************************/
/* I2C configuration */
diff --git a/include/timer.h b/include/timer.h
index fb7800ce2e..4a008f6d06 100644
--- a/include/timer.h
+++ b/include/timer.h
@@ -71,7 +71,7 @@ int timestamp_expired(timestamp_t deadline, const timestamp_t *now);
*
* @param us Number of microseconds to delay.
*/
-void udelay(unsigned us);
+__override_proto void udelay(unsigned us);
/**
* Sleep.