1*9055c7d1SRyan Harkin /* 2*9055c7d1SRyan Harkin * Copyright (c) 2015, ARM Limited and Contributors. All rights reserved. 3*9055c7d1SRyan Harkin * 4*9055c7d1SRyan Harkin * Redistribution and use in source and binary forms, with or without 5*9055c7d1SRyan Harkin * modification, are permitted provided that the following conditions are met: 6*9055c7d1SRyan Harkin * 7*9055c7d1SRyan Harkin * Redistributions of source code must retain the above copyright notice, this 8*9055c7d1SRyan Harkin * list of conditions and the following disclaimer. 9*9055c7d1SRyan Harkin * 10*9055c7d1SRyan Harkin * Redistributions in binary form must reproduce the above copyright notice, 11*9055c7d1SRyan Harkin * this list of conditions and the following disclaimer in the documentation 12*9055c7d1SRyan Harkin * and/or other materials provided with the distribution. 13*9055c7d1SRyan Harkin * 14*9055c7d1SRyan Harkin * Neither the name of ARM nor the names of its contributors may be used 15*9055c7d1SRyan Harkin * to endorse or promote products derived from this software without specific 16*9055c7d1SRyan Harkin * prior written permission. 17*9055c7d1SRyan Harkin * 18*9055c7d1SRyan Harkin * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 19*9055c7d1SRyan Harkin * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 20*9055c7d1SRyan Harkin * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 21*9055c7d1SRyan Harkin * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE 22*9055c7d1SRyan Harkin * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 23*9055c7d1SRyan Harkin * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 24*9055c7d1SRyan Harkin * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 25*9055c7d1SRyan Harkin * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 26*9055c7d1SRyan Harkin * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 27*9055c7d1SRyan Harkin * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 28*9055c7d1SRyan Harkin * POSSIBILITY OF SUCH DAMAGE. 29*9055c7d1SRyan Harkin */ 30*9055c7d1SRyan Harkin 31*9055c7d1SRyan Harkin #include <assert.h> 32*9055c7d1SRyan Harkin #include <delay_timer.h> 33*9055c7d1SRyan Harkin #include <platform_def.h> 34*9055c7d1SRyan Harkin 35*9055c7d1SRyan Harkin /*********************************************************** 36*9055c7d1SRyan Harkin * The delay timer implementation 37*9055c7d1SRyan Harkin ***********************************************************/ 38*9055c7d1SRyan Harkin static const timer_ops_t *ops; 39*9055c7d1SRyan Harkin 40*9055c7d1SRyan Harkin /*********************************************************** 41*9055c7d1SRyan Harkin * Delay for the given number of microseconds. The driver must 42*9055c7d1SRyan Harkin * be initialized before calling this function. 43*9055c7d1SRyan Harkin ***********************************************************/ 44*9055c7d1SRyan Harkin void udelay(uint32_t usec) 45*9055c7d1SRyan Harkin { 46*9055c7d1SRyan Harkin assert(ops != 0 && 47*9055c7d1SRyan Harkin (ops->clk_mult != 0) && 48*9055c7d1SRyan Harkin (ops->clk_div != 0) && 49*9055c7d1SRyan Harkin (ops->get_timer_value != 0)); 50*9055c7d1SRyan Harkin 51*9055c7d1SRyan Harkin uint32_t start, cnt, delta, delta_us; 52*9055c7d1SRyan Harkin 53*9055c7d1SRyan Harkin /* counter is decreasing */ 54*9055c7d1SRyan Harkin start = ops->get_timer_value(); 55*9055c7d1SRyan Harkin do { 56*9055c7d1SRyan Harkin cnt = ops->get_timer_value(); 57*9055c7d1SRyan Harkin if (cnt > start) { 58*9055c7d1SRyan Harkin delta = UINT32_MAX - cnt; 59*9055c7d1SRyan Harkin delta += start; 60*9055c7d1SRyan Harkin } else 61*9055c7d1SRyan Harkin delta = start - cnt; 62*9055c7d1SRyan Harkin delta_us = (delta * ops->clk_mult) / ops->clk_div; 63*9055c7d1SRyan Harkin } while (delta_us < usec); 64*9055c7d1SRyan Harkin } 65*9055c7d1SRyan Harkin 66*9055c7d1SRyan Harkin /*********************************************************** 67*9055c7d1SRyan Harkin * Delay for the given number of milliseconds. The driver must 68*9055c7d1SRyan Harkin * be initialized before calling this function. 69*9055c7d1SRyan Harkin ***********************************************************/ 70*9055c7d1SRyan Harkin void mdelay(uint32_t msec) 71*9055c7d1SRyan Harkin { 72*9055c7d1SRyan Harkin udelay(msec*1000); 73*9055c7d1SRyan Harkin } 74*9055c7d1SRyan Harkin 75*9055c7d1SRyan Harkin /*********************************************************** 76*9055c7d1SRyan Harkin * Initialize the timer. The fields in the provided timer 77*9055c7d1SRyan Harkin * ops pointer must be valid. 78*9055c7d1SRyan Harkin ***********************************************************/ 79*9055c7d1SRyan Harkin void timer_init(const timer_ops_t *ops_ptr) 80*9055c7d1SRyan Harkin { 81*9055c7d1SRyan Harkin assert(ops_ptr != 0 && 82*9055c7d1SRyan Harkin (ops_ptr->clk_mult != 0) && 83*9055c7d1SRyan Harkin (ops_ptr->clk_div != 0) && 84*9055c7d1SRyan Harkin (ops_ptr->get_timer_value != 0)); 85*9055c7d1SRyan Harkin 86*9055c7d1SRyan Harkin ops = ops_ptr; 87*9055c7d1SRyan Harkin } 88