summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authordavidcunado-arm <david.cunado@arm.com>2018-01-30 08:59:35 +0000
committerGitHub <noreply@github.com>2018-01-30 08:59:35 +0000
commiteefd04b69cedfbdedfe4b2db2b29f466692a4580 (patch)
treedf413bc9fa309ae56d2e6a9c5c5b5295a9246f9a
parente47541ac6ef58b213fd915253e16e6fa1ae3b4a9 (diff)
parente2aec918d07237e4a6aa185ad2d267750e8f2883 (diff)
Merge pull request #1235 from jwerner-chromium/JW_udelay
Fix udelay issues that can make duration slightly too short
-rw-r--r--drivers/delay_timer/delay_timer.c4
-rw-r--r--include/lib/utils_def.h10
2 files changed, 8 insertions, 6 deletions
diff --git a/drivers/delay_timer/delay_timer.c b/drivers/delay_timer/delay_timer.c
index 43f5af7b..c9f84d77 100644
--- a/drivers/delay_timer/delay_timer.c
+++ b/drivers/delay_timer/delay_timer.c
@@ -7,6 +7,7 @@
#include <assert.h>
#include <delay_timer.h>
#include <platform_def.h>
+#include <utils_def.h>
/***********************************************************
* The delay timer implementation
@@ -30,7 +31,8 @@ void udelay(uint32_t usec)
start = ops->get_timer_value();
- total_delta = (usec * ops->clk_div) / ops->clk_mult;
+ /* Add an extra tick to avoid delaying less than requested. */
+ total_delta = div_round_up(usec * ops->clk_div, ops->clk_mult) + 1;
do {
/*
diff --git a/include/lib/utils_def.h b/include/lib/utils_def.h
index bda3b073..ecb261a1 100644
--- a/include/lib/utils_def.h
+++ b/include/lib/utils_def.h
@@ -24,6 +24,11 @@
*/
#define DIV_ROUND_UP_2EVAL(n, d) (((n) + (d) - 1) / (d))
+#define div_round_up(val, div) __extension__ ({ \
+ __typeof__(div) _div = (div); \
+ ((val) + _div - 1) / _div; \
+})
+
#define MIN(x, y) __extension__ ({ \
__typeof__(x) _x = (x); \
__typeof__(y) _y = (y); \
@@ -55,11 +60,6 @@
#define round_down(value, boundary) \
((value) & ~round_boundary(value, boundary))
-#define div_round_up(val, div) __extension__ ({ \
- __typeof__(div) _div = (div); \
- round_up((val), _div)/_div; \
-})
-
/*
* Evaluates to 1 if (ptr + inc) overflows, 0 otherwise.
* Both arguments must be unsigned pointer values (i.e. uintptr_t).