summaryrefslogtreecommitdiff
path: root/drivers/delay_timer/delay_timer.c
diff options
context:
space:
mode:
authorAntonio Nino Diaz <antonio.ninodiaz@arm.com>2016-05-18 10:37:25 +0100
committerAntonio Nino Diaz <antonio.ninodiaz@arm.com>2016-05-20 15:29:30 +0100
commit0bcedb2212bd2436834117cd956d7b6e16b11673 (patch)
tree88371f100412d5d817405ca7b10e6efc91115020 /drivers/delay_timer/delay_timer.c
parentf3d3b316f82faa88e42f3d09c97cd9e52ac92599 (diff)
Implement generic delay timer
Add delay timer implementation based on the system generic counter. This either uses the platform's implementation of `plat_get_syscnt_freq()` or explicit clock multiplier/divider values provided by the platform. The current implementation of udelay has been modified to avoid unnecessary calculations while waiting on the loop and to make it easier to check for overflows. Change-Id: I9062e1d506dc2f68367fd9289250b93444721732
Diffstat (limited to 'drivers/delay_timer/delay_timer.c')
-rw-r--r--drivers/delay_timer/delay_timer.c23
1 files changed, 13 insertions, 10 deletions
diff --git a/drivers/delay_timer/delay_timer.c b/drivers/delay_timer/delay_timer.c
index 0bee876f..ed7ed52e 100644
--- a/drivers/delay_timer/delay_timer.c
+++ b/drivers/delay_timer/delay_timer.c
@@ -48,19 +48,22 @@ void udelay(uint32_t usec)
(ops->clk_div != 0) &&
(ops->get_timer_value != 0));
- uint32_t start, cnt, delta, delta_us;
+ uint32_t start, delta, total_delta;
+
+ assert(usec < UINT32_MAX / ops->clk_div);
- /* counter is decreasing */
start = ops->get_timer_value();
+
+ total_delta = (usec * ops->clk_div) / ops->clk_mult;
+
do {
- cnt = ops->get_timer_value();
- if (cnt > start) {
- delta = UINT32_MAX - cnt;
- delta += start;
- } else
- delta = start - cnt;
- delta_us = (delta * ops->clk_mult) / ops->clk_div;
- } while (delta_us < usec);
+ /*
+ * If the timer value wraps around, the subtraction will
+ * overflow and it will still give the correct result.
+ */
+ delta = start - ops->get_timer_value(); /* Decreasing counter */
+
+ } while (delta < total_delta);
}
/***********************************************************