Merge "TF-A: Fix non-standard frequency issue in udelay" into integration
diff --git a/drivers/delay_timer/delay_timer.c b/drivers/delay_timer/delay_timer.c
index 8c2996e..a3fd7bf 100644
--- a/drivers/delay_timer/delay_timer.c
+++ b/drivers/delay_timer/delay_timer.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2015-2018, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2015-2019, ARM Limited and Contributors. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -27,23 +27,32 @@
 		(timer_ops->clk_div != 0U) &&
 		(timer_ops->get_timer_value != NULL));
 
-	uint32_t start, delta, total_delta;
+	uint32_t start, delta;
+	uint64_t total_delta;
 
-	assert(usec < (UINT32_MAX / timer_ops->clk_div));
+	assert(usec < (UINT64_MAX / timer_ops->clk_div));
 
 	start = timer_ops->get_timer_value();
 
 	/* Add an extra tick to avoid delaying less than requested. */
 	total_delta =
-		div_round_up(usec * timer_ops->clk_div,
+		div_round_up((uint64_t)usec * timer_ops->clk_div,
 						timer_ops->clk_mult) + 1U;
+	/*
+	 * Precaution for the total_delta ~ UINT32_MAX and the fact that we
+	 * cannot catch every tick of the timer.
+	 * For example 100MHz timer over 25MHz APB will miss at least 4 ticks.
+	 * 1000U is an arbitrary big number which is believed to be sufficient.
+	 */
+	assert(total_delta < (UINT32_MAX - 1000U));
 
 	do {
 		/*
 		 * If the timer value wraps around, the subtraction will
 		 * overflow and it will still give the correct result.
+		 * delta is decreasing counter
 		 */
-		delta = start - timer_ops->get_timer_value(); /* Decreasing counter */
+		delta = start - timer_ops->get_timer_value();
 
 	} while (delta < total_delta);
 }
@@ -54,6 +63,7 @@
  ***********************************************************/
 void mdelay(uint32_t msec)
 {
+	assert((msec * 1000UL) < UINT32_MAX);
 	udelay(msec * 1000U);
 }