xref: /openbmc/linux/arch/alpha/lib/udelay.c (revision 498495dba268b20e8eadd7fe93c140c68b6cc9d2)
1*b2441318SGreg Kroah-Hartman // SPDX-License-Identifier: GPL-2.0
21da177e4SLinus Torvalds /*
31da177e4SLinus Torvalds  * Copyright (C) 1993, 2000 Linus Torvalds
41da177e4SLinus Torvalds  *
51da177e4SLinus Torvalds  * Delay routines, using a pre-computed "loops_per_jiffy" value.
61da177e4SLinus Torvalds  */
71da177e4SLinus Torvalds 
81da177e4SLinus Torvalds #include <linux/module.h>
91da177e4SLinus Torvalds #include <linux/sched.h> /* for udelay's use of smp_processor_id */
101da177e4SLinus Torvalds #include <asm/param.h>
111da177e4SLinus Torvalds #include <asm/smp.h>
121da177e4SLinus Torvalds #include <linux/delay.h>
131da177e4SLinus Torvalds 
141da177e4SLinus Torvalds /*
151da177e4SLinus Torvalds  * Use only for very small delays (< 1 msec).
161da177e4SLinus Torvalds  *
171da177e4SLinus Torvalds  * The active part of our cycle counter is only 32-bits wide, and
181da177e4SLinus Torvalds  * we're treating the difference between two marks as signed.  On
191da177e4SLinus Torvalds  * a 1GHz box, that's about 2 seconds.
201da177e4SLinus Torvalds  */
211da177e4SLinus Torvalds 
221da177e4SLinus Torvalds void
__delay(int loops)231da177e4SLinus Torvalds __delay(int loops)
241da177e4SLinus Torvalds {
251da177e4SLinus Torvalds 	int tmp;
261da177e4SLinus Torvalds 	__asm__ __volatile__(
271da177e4SLinus Torvalds 		"	rpcc %0\n"
281da177e4SLinus Torvalds 		"	addl %1,%0,%1\n"
291da177e4SLinus Torvalds 		"1:	rpcc %0\n"
301da177e4SLinus Torvalds 		"	subl %1,%0,%0\n"
311da177e4SLinus Torvalds 		"	bgt %0,1b"
321da177e4SLinus Torvalds 		: "=&r" (tmp), "=r" (loops) : "1"(loops));
331da177e4SLinus Torvalds }
3414b97dedSSudip Mukherjee EXPORT_SYMBOL(__delay);
351da177e4SLinus Torvalds 
361da177e4SLinus Torvalds #ifdef CONFIG_SMP
371da177e4SLinus Torvalds #define LPJ	 cpu_data[smp_processor_id()].loops_per_jiffy
381da177e4SLinus Torvalds #else
391da177e4SLinus Torvalds #define LPJ	 loops_per_jiffy
401da177e4SLinus Torvalds #endif
411da177e4SLinus Torvalds 
421da177e4SLinus Torvalds void
udelay(unsigned long usecs)431da177e4SLinus Torvalds udelay(unsigned long usecs)
441da177e4SLinus Torvalds {
451da177e4SLinus Torvalds 	usecs *= (((unsigned long)HZ << 32) / 1000000) * LPJ;
461da177e4SLinus Torvalds 	__delay((long)usecs >> 32);
471da177e4SLinus Torvalds }
481da177e4SLinus Torvalds EXPORT_SYMBOL(udelay);
491da177e4SLinus Torvalds 
501da177e4SLinus Torvalds void
ndelay(unsigned long nsecs)511da177e4SLinus Torvalds ndelay(unsigned long nsecs)
521da177e4SLinus Torvalds {
531da177e4SLinus Torvalds 	nsecs *= (((unsigned long)HZ << 32) / 1000000000) * LPJ;
541da177e4SLinus Torvalds 	__delay((long)nsecs >> 32);
551da177e4SLinus Torvalds }
561da177e4SLinus Torvalds EXPORT_SYMBOL(ndelay);
57