1*4882a593Smuzhiyun /* 2*4882a593Smuzhiyun * include/asm-xtensa/delay.h 3*4882a593Smuzhiyun * 4*4882a593Smuzhiyun * This file is subject to the terms and conditions of the GNU General Public 5*4882a593Smuzhiyun * License. See the file "COPYING" in the main directory of this archive 6*4882a593Smuzhiyun * for more details. 7*4882a593Smuzhiyun * 8*4882a593Smuzhiyun * Copyright (C) 2001 - 2005 Tensilica Inc. 9*4882a593Smuzhiyun * 10*4882a593Smuzhiyun */ 11*4882a593Smuzhiyun 12*4882a593Smuzhiyun #ifndef _XTENSA_DELAY_H 13*4882a593Smuzhiyun #define _XTENSA_DELAY_H 14*4882a593Smuzhiyun 15*4882a593Smuzhiyun #include <asm/timex.h> 16*4882a593Smuzhiyun #include <asm/param.h> 17*4882a593Smuzhiyun 18*4882a593Smuzhiyun extern unsigned long loops_per_jiffy; 19*4882a593Smuzhiyun __delay(unsigned long loops)20*4882a593Smuzhiyunstatic inline void __delay(unsigned long loops) 21*4882a593Smuzhiyun { 22*4882a593Smuzhiyun if (__builtin_constant_p(loops) && loops < 2) 23*4882a593Smuzhiyun __asm__ __volatile__ ("nop"); 24*4882a593Smuzhiyun else if (loops >= 2) 25*4882a593Smuzhiyun /* 2 cycles per loop. */ 26*4882a593Smuzhiyun __asm__ __volatile__ ("1: addi %0, %0, -2; bgeui %0, 2, 1b" 27*4882a593Smuzhiyun : "+r" (loops)); 28*4882a593Smuzhiyun } 29*4882a593Smuzhiyun 30*4882a593Smuzhiyun /* Undefined function to get compile-time error */ 31*4882a593Smuzhiyun void __bad_udelay(void); 32*4882a593Smuzhiyun void __bad_ndelay(void); 33*4882a593Smuzhiyun 34*4882a593Smuzhiyun #define __MAX_UDELAY 30000 35*4882a593Smuzhiyun #define __MAX_NDELAY 30000 36*4882a593Smuzhiyun __udelay(unsigned long usecs)37*4882a593Smuzhiyunstatic inline void __udelay(unsigned long usecs) 38*4882a593Smuzhiyun { 39*4882a593Smuzhiyun unsigned long start = get_ccount(); 40*4882a593Smuzhiyun unsigned long cycles = (usecs * (ccount_freq >> 15)) >> 5; 41*4882a593Smuzhiyun 42*4882a593Smuzhiyun /* Note: all variables are unsigned (can wrap around)! */ 43*4882a593Smuzhiyun while (((unsigned long)get_ccount()) - start < cycles) 44*4882a593Smuzhiyun cpu_relax(); 45*4882a593Smuzhiyun } 46*4882a593Smuzhiyun udelay(unsigned long usec)47*4882a593Smuzhiyunstatic inline void udelay(unsigned long usec) 48*4882a593Smuzhiyun { 49*4882a593Smuzhiyun if (__builtin_constant_p(usec) && usec >= __MAX_UDELAY) 50*4882a593Smuzhiyun __bad_udelay(); 51*4882a593Smuzhiyun else 52*4882a593Smuzhiyun __udelay(usec); 53*4882a593Smuzhiyun } 54*4882a593Smuzhiyun __ndelay(unsigned long nsec)55*4882a593Smuzhiyunstatic inline void __ndelay(unsigned long nsec) 56*4882a593Smuzhiyun { 57*4882a593Smuzhiyun /* 58*4882a593Smuzhiyun * Inner shift makes sure multiplication doesn't overflow 59*4882a593Smuzhiyun * for legitimate nsec values 60*4882a593Smuzhiyun */ 61*4882a593Smuzhiyun unsigned long cycles = (nsec * (ccount_freq >> 15)) >> 15; 62*4882a593Smuzhiyun __delay(cycles); 63*4882a593Smuzhiyun } 64*4882a593Smuzhiyun 65*4882a593Smuzhiyun #define ndelay(n) ndelay(n) 66*4882a593Smuzhiyun ndelay(unsigned long nsec)67*4882a593Smuzhiyunstatic inline void ndelay(unsigned long nsec) 68*4882a593Smuzhiyun { 69*4882a593Smuzhiyun if (__builtin_constant_p(nsec) && nsec >= __MAX_NDELAY) 70*4882a593Smuzhiyun __bad_ndelay(); 71*4882a593Smuzhiyun else 72*4882a593Smuzhiyun __ndelay(nsec); 73*4882a593Smuzhiyun } 74*4882a593Smuzhiyun 75*4882a593Smuzhiyun #endif 76