Back to home page

OSCL-LXR

 
 

    


0001 /* SPDX-License-Identifier: GPL-2.0-only */
0002 /*
0003  * Copyright (C) 2004, 2007-2010, 2011-2012 Synopsys, Inc. (www.synopsys.com)
0004  *
0005  * Delay routines using pre computed loops_per_jiffy value.
0006  *
0007  * vineetg: Feb 2012
0008  *  -Rewrote in "C" to avoid dealing with availability of H/w MPY
0009  *  -Also reduced the num of MPY operations from 3 to 2
0010  *
0011  * Amit Bhor: Codito Technologies 2004
0012  */
0013 
0014 #ifndef __ASM_ARC_UDELAY_H
0015 #define __ASM_ARC_UDELAY_H
0016 
0017 #include <asm-generic/types.h>
0018 #include <asm/param.h>      /* HZ */
0019 
0020 extern unsigned long loops_per_jiffy;
0021 
0022 static inline void __delay(unsigned long loops)
0023 {
0024     __asm__ __volatile__(
0025     "   mov lp_count, %0    \n"
0026     "   lp  1f          \n"
0027     "   nop         \n"
0028     "1:             \n"
0029     :
0030         : "r"(loops)
0031         : "lp_count");
0032 }
0033 
0034 extern void __bad_udelay(void);
0035 
0036 /*
0037  * Normal Math for computing loops in "N" usecs
0038  *  -we have precomputed @loops_per_jiffy
0039  *  -1 sec has HZ jiffies
0040  * loops per "N" usecs = ((loops_per_jiffy * HZ / 1000000) * N)
0041  *
0042  * Approximate Division by multiplication:
0043  *  -Mathematically if we multiply and divide a number by same value the
0044  *   result remains unchanged:  In this case, we use 2^32
0045  *  -> (loops_per_N_usec * 2^32 ) / 2^32
0046  *  -> (((loops_per_jiffy * HZ / 1000000) * N) * 2^32) / 2^32
0047  *  -> (loops_per_jiffy * HZ * N * 4295) / 2^32
0048  *
0049  *  -Divide by 2^32 is very simply right shift by 32
0050  *  -We simply need to ensure that the multiply per above eqn happens in
0051  *   64-bit precision (if CPU doesn't support it - gcc can emaulate it)
0052  */
0053 
0054 static inline void __udelay(unsigned long usecs)
0055 {
0056     unsigned long loops;
0057 
0058     /* (u64) cast ensures 64 bit MPY - real or emulated
0059      * HZ * 4295 is pre-evaluated by gcc - hence only 2 mpy ops
0060      */
0061     loops = ((u64) usecs * 4295 * HZ * loops_per_jiffy) >> 32;
0062 
0063     __delay(loops);
0064 }
0065 
0066 #define udelay(n) (__builtin_constant_p(n) ? ((n) > 20000 ? __bad_udelay() \
0067                 : __udelay(n)) : __udelay(n))
0068 
0069 #endif /* __ASM_ARC_UDELAY_H */