1 /* 2 * Copyright (c) 2015, ARM Limited and Contributors. All rights reserved. 3 * 4 * SPDX-License-Identifier: BSD-3-Clause 5 */ 6 7 #include <assert.h> 8 #include <delay_timer.h> 9 #include <platform_def.h> 10 #include <utils_def.h> 11 12 /*********************************************************** 13 * The delay timer implementation 14 ***********************************************************/ 15 static const timer_ops_t *ops; 16 17 /*********************************************************** 18 * Delay for the given number of microseconds. The driver must 19 * be initialized before calling this function. 20 ***********************************************************/ 21 void udelay(uint32_t usec) 22 { 23 assert(ops != NULL && 24 (ops->clk_mult != 0) && 25 (ops->clk_div != 0) && 26 (ops->get_timer_value != NULL)); 27 28 uint32_t start, delta, total_delta; 29 30 assert(usec < UINT32_MAX / ops->clk_div); 31 32 start = ops->get_timer_value(); 33 34 /* Add an extra tick to avoid delaying less than requested. */ 35 total_delta = div_round_up(usec * ops->clk_div, ops->clk_mult) + 1; 36 37 do { 38 /* 39 * If the timer value wraps around, the subtraction will 40 * overflow and it will still give the correct result. 41 */ 42 delta = start - ops->get_timer_value(); /* Decreasing counter */ 43 44 } while (delta < total_delta); 45 } 46 47 /*********************************************************** 48 * Delay for the given number of milliseconds. The driver must 49 * be initialized before calling this function. 50 ***********************************************************/ 51 void mdelay(uint32_t msec) 52 { 53 udelay(msec*1000); 54 } 55 56 /*********************************************************** 57 * Initialize the timer. The fields in the provided timer 58 * ops pointer must be valid. 59 ***********************************************************/ 60 void timer_init(const timer_ops_t *ops_ptr) 61 { 62 assert(ops_ptr != NULL && 63 (ops_ptr->clk_mult != 0) && 64 (ops_ptr->clk_div != 0) && 65 (ops_ptr->get_timer_value != NULL)); 66 67 ops = ops_ptr; 68 } 69