diff options
author | Antonio Nino Diaz <antonio.ninodiaz@arm.com> | 2016-05-18 10:37:25 +0100 |
---|---|---|
committer | Antonio Nino Diaz <antonio.ninodiaz@arm.com> | 2016-05-20 15:29:30 +0100 |
commit | 0bcedb2212bd2436834117cd956d7b6e16b11673 (patch) | |
tree | 88371f100412d5d817405ca7b10e6efc91115020 /drivers/delay_timer/delay_timer.c | |
parent | f3d3b316f82faa88e42f3d09c97cd9e52ac92599 (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.c | 23 |
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); } /*********************************************************** |