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