1*4882a593Smuzhiyun /* SPDX-License-Identifier: GPL-2.0-only */ 2*4882a593Smuzhiyun /* 3*4882a593Smuzhiyun * Copyright (C) 2004, 2007-2010, 2011-2012 Synopsys, Inc. (www.synopsys.com) 4*4882a593Smuzhiyun * 5*4882a593Smuzhiyun * Delay routines using pre computed loops_per_jiffy value. 6*4882a593Smuzhiyun * 7*4882a593Smuzhiyun * vineetg: Feb 2012 8*4882a593Smuzhiyun * -Rewrote in "C" to avoid dealing with availability of H/w MPY 9*4882a593Smuzhiyun * -Also reduced the num of MPY operations from 3 to 2 10*4882a593Smuzhiyun * 11*4882a593Smuzhiyun * Amit Bhor: Codito Technologies 2004 12*4882a593Smuzhiyun */ 13*4882a593Smuzhiyun 14*4882a593Smuzhiyun #ifndef __ASM_ARC_UDELAY_H 15*4882a593Smuzhiyun #define __ASM_ARC_UDELAY_H 16*4882a593Smuzhiyun 17*4882a593Smuzhiyun #include <asm-generic/types.h> 18*4882a593Smuzhiyun #include <asm/param.h> /* HZ */ 19*4882a593Smuzhiyun 20*4882a593Smuzhiyun extern unsigned long loops_per_jiffy; 21*4882a593Smuzhiyun __delay(unsigned long loops)22*4882a593Smuzhiyunstatic inline void __delay(unsigned long loops) 23*4882a593Smuzhiyun { 24*4882a593Smuzhiyun __asm__ __volatile__( 25*4882a593Smuzhiyun " mov lp_count, %0 \n" 26*4882a593Smuzhiyun " lp 1f \n" 27*4882a593Smuzhiyun " nop \n" 28*4882a593Smuzhiyun "1: \n" 29*4882a593Smuzhiyun : 30*4882a593Smuzhiyun : "r"(loops) 31*4882a593Smuzhiyun : "lp_count"); 32*4882a593Smuzhiyun } 33*4882a593Smuzhiyun 34*4882a593Smuzhiyun extern void __bad_udelay(void); 35*4882a593Smuzhiyun 36*4882a593Smuzhiyun /* 37*4882a593Smuzhiyun * Normal Math for computing loops in "N" usecs 38*4882a593Smuzhiyun * -we have precomputed @loops_per_jiffy 39*4882a593Smuzhiyun * -1 sec has HZ jiffies 40*4882a593Smuzhiyun * loops per "N" usecs = ((loops_per_jiffy * HZ / 1000000) * N) 41*4882a593Smuzhiyun * 42*4882a593Smuzhiyun * Approximate Division by multiplication: 43*4882a593Smuzhiyun * -Mathematically if we multiply and divide a number by same value the 44*4882a593Smuzhiyun * result remains unchanged: In this case, we use 2^32 45*4882a593Smuzhiyun * -> (loops_per_N_usec * 2^32 ) / 2^32 46*4882a593Smuzhiyun * -> (((loops_per_jiffy * HZ / 1000000) * N) * 2^32) / 2^32 47*4882a593Smuzhiyun * -> (loops_per_jiffy * HZ * N * 4295) / 2^32 48*4882a593Smuzhiyun * 49*4882a593Smuzhiyun * -Divide by 2^32 is very simply right shift by 32 50*4882a593Smuzhiyun * -We simply need to ensure that the multiply per above eqn happens in 51*4882a593Smuzhiyun * 64-bit precision (if CPU doesn't support it - gcc can emaulate it) 52*4882a593Smuzhiyun */ 53*4882a593Smuzhiyun __udelay(unsigned long usecs)54*4882a593Smuzhiyunstatic inline void __udelay(unsigned long usecs) 55*4882a593Smuzhiyun { 56*4882a593Smuzhiyun unsigned long loops; 57*4882a593Smuzhiyun 58*4882a593Smuzhiyun /* (u64) cast ensures 64 bit MPY - real or emulated 59*4882a593Smuzhiyun * HZ * 4295 is pre-evaluated by gcc - hence only 2 mpy ops 60*4882a593Smuzhiyun */ 61*4882a593Smuzhiyun loops = ((u64) usecs * 4295 * HZ * loops_per_jiffy) >> 32; 62*4882a593Smuzhiyun 63*4882a593Smuzhiyun __delay(loops); 64*4882a593Smuzhiyun } 65*4882a593Smuzhiyun 66*4882a593Smuzhiyun #define udelay(n) (__builtin_constant_p(n) ? ((n) > 20000 ? __bad_udelay() \ 67*4882a593Smuzhiyun : __udelay(n)) : __udelay(n)) 68*4882a593Smuzhiyun 69*4882a593Smuzhiyun #endif /* __ASM_ARC_UDELAY_H */ 70