18c2ecf20Sopenharmony_ci/* 28c2ecf20Sopenharmony_ci * include/asm-xtensa/delay.h 38c2ecf20Sopenharmony_ci * 48c2ecf20Sopenharmony_ci * This file is subject to the terms and conditions of the GNU General Public 58c2ecf20Sopenharmony_ci * License. See the file "COPYING" in the main directory of this archive 68c2ecf20Sopenharmony_ci * for more details. 78c2ecf20Sopenharmony_ci * 88c2ecf20Sopenharmony_ci * Copyright (C) 2001 - 2005 Tensilica Inc. 98c2ecf20Sopenharmony_ci * 108c2ecf20Sopenharmony_ci */ 118c2ecf20Sopenharmony_ci 128c2ecf20Sopenharmony_ci#ifndef _XTENSA_DELAY_H 138c2ecf20Sopenharmony_ci#define _XTENSA_DELAY_H 148c2ecf20Sopenharmony_ci 158c2ecf20Sopenharmony_ci#include <asm/timex.h> 168c2ecf20Sopenharmony_ci#include <asm/param.h> 178c2ecf20Sopenharmony_ci 188c2ecf20Sopenharmony_ciextern unsigned long loops_per_jiffy; 198c2ecf20Sopenharmony_ci 208c2ecf20Sopenharmony_cistatic inline void __delay(unsigned long loops) 218c2ecf20Sopenharmony_ci{ 228c2ecf20Sopenharmony_ci if (__builtin_constant_p(loops) && loops < 2) 238c2ecf20Sopenharmony_ci __asm__ __volatile__ ("nop"); 248c2ecf20Sopenharmony_ci else if (loops >= 2) 258c2ecf20Sopenharmony_ci /* 2 cycles per loop. */ 268c2ecf20Sopenharmony_ci __asm__ __volatile__ ("1: addi %0, %0, -2; bgeui %0, 2, 1b" 278c2ecf20Sopenharmony_ci : "+r" (loops)); 288c2ecf20Sopenharmony_ci} 298c2ecf20Sopenharmony_ci 308c2ecf20Sopenharmony_ci/* Undefined function to get compile-time error */ 318c2ecf20Sopenharmony_civoid __bad_udelay(void); 328c2ecf20Sopenharmony_civoid __bad_ndelay(void); 338c2ecf20Sopenharmony_ci 348c2ecf20Sopenharmony_ci#define __MAX_UDELAY 30000 358c2ecf20Sopenharmony_ci#define __MAX_NDELAY 30000 368c2ecf20Sopenharmony_ci 378c2ecf20Sopenharmony_cistatic inline void __udelay(unsigned long usecs) 388c2ecf20Sopenharmony_ci{ 398c2ecf20Sopenharmony_ci unsigned long start = get_ccount(); 408c2ecf20Sopenharmony_ci unsigned long cycles = (usecs * (ccount_freq >> 15)) >> 5; 418c2ecf20Sopenharmony_ci 428c2ecf20Sopenharmony_ci /* Note: all variables are unsigned (can wrap around)! */ 438c2ecf20Sopenharmony_ci while (((unsigned long)get_ccount()) - start < cycles) 448c2ecf20Sopenharmony_ci cpu_relax(); 458c2ecf20Sopenharmony_ci} 468c2ecf20Sopenharmony_ci 478c2ecf20Sopenharmony_cistatic inline void udelay(unsigned long usec) 488c2ecf20Sopenharmony_ci{ 498c2ecf20Sopenharmony_ci if (__builtin_constant_p(usec) && usec >= __MAX_UDELAY) 508c2ecf20Sopenharmony_ci __bad_udelay(); 518c2ecf20Sopenharmony_ci else 528c2ecf20Sopenharmony_ci __udelay(usec); 538c2ecf20Sopenharmony_ci} 548c2ecf20Sopenharmony_ci 558c2ecf20Sopenharmony_cistatic inline void __ndelay(unsigned long nsec) 568c2ecf20Sopenharmony_ci{ 578c2ecf20Sopenharmony_ci /* 588c2ecf20Sopenharmony_ci * Inner shift makes sure multiplication doesn't overflow 598c2ecf20Sopenharmony_ci * for legitimate nsec values 608c2ecf20Sopenharmony_ci */ 618c2ecf20Sopenharmony_ci unsigned long cycles = (nsec * (ccount_freq >> 15)) >> 15; 628c2ecf20Sopenharmony_ci __delay(cycles); 638c2ecf20Sopenharmony_ci} 648c2ecf20Sopenharmony_ci 658c2ecf20Sopenharmony_ci#define ndelay(n) ndelay(n) 668c2ecf20Sopenharmony_ci 678c2ecf20Sopenharmony_cistatic inline void ndelay(unsigned long nsec) 688c2ecf20Sopenharmony_ci{ 698c2ecf20Sopenharmony_ci if (__builtin_constant_p(nsec) && nsec >= __MAX_NDELAY) 708c2ecf20Sopenharmony_ci __bad_ndelay(); 718c2ecf20Sopenharmony_ci else 728c2ecf20Sopenharmony_ci __ndelay(nsec); 738c2ecf20Sopenharmony_ci} 748c2ecf20Sopenharmony_ci 758c2ecf20Sopenharmony_ci#endif 76