blob: 403c60fdf96ff2636816e7033b9c88ee4497af5a [file] [log] [blame]
Ryan Harkin32539fc2015-03-17 14:50:05 +00001/*
2 * Copyright (c) 2015, ARM Limited and Contributors. All rights reserved.
3 *
dp-armfa3cf0b2017-05-03 09:38:09 +01004 * SPDX-License-Identifier: BSD-3-Clause
Ryan Harkin32539fc2015-03-17 14:50:05 +00005 */
6
7#include <assert.h>
8#include <delay_timer.h>
9#include <platform_def.h>
10
11/***********************************************************
12 * The delay timer implementation
13 ***********************************************************/
14static const timer_ops_t *ops;
15
16/***********************************************************
17 * Delay for the given number of microseconds. The driver must
18 * be initialized before calling this function.
19 ***********************************************************/
20void udelay(uint32_t usec)
21{
22 assert(ops != 0 &&
23 (ops->clk_mult != 0) &&
24 (ops->clk_div != 0) &&
25 (ops->get_timer_value != 0));
26
Antonio Nino Diazbcd79b22016-05-18 10:37:25 +010027 uint32_t start, delta, total_delta;
Ryan Harkin32539fc2015-03-17 14:50:05 +000028
Antonio Nino Diazbcd79b22016-05-18 10:37:25 +010029 assert(usec < UINT32_MAX / ops->clk_div);
30
Ryan Harkin32539fc2015-03-17 14:50:05 +000031 start = ops->get_timer_value();
Antonio Nino Diazbcd79b22016-05-18 10:37:25 +010032
33 total_delta = (usec * ops->clk_div) / ops->clk_mult;
34
Ryan Harkin32539fc2015-03-17 14:50:05 +000035 do {
Antonio Nino Diazbcd79b22016-05-18 10:37:25 +010036 /*
37 * If the timer value wraps around, the subtraction will
38 * overflow and it will still give the correct result.
39 */
40 delta = start - ops->get_timer_value(); /* Decreasing counter */
41
42 } while (delta < total_delta);
Ryan Harkin32539fc2015-03-17 14:50:05 +000043}
44
45/***********************************************************
46 * Delay for the given number of milliseconds. The driver must
47 * be initialized before calling this function.
48 ***********************************************************/
49void mdelay(uint32_t msec)
50{
51 udelay(msec*1000);
52}
53
54/***********************************************************
55 * Initialize the timer. The fields in the provided timer
56 * ops pointer must be valid.
57 ***********************************************************/
58void timer_init(const timer_ops_t *ops_ptr)
59{
60 assert(ops_ptr != 0 &&
61 (ops_ptr->clk_mult != 0) &&
62 (ops_ptr->clk_div != 0) &&
63 (ops_ptr->get_timer_value != 0));
64
65 ops = ops_ptr;
66}