1*b2441318SGreg Kroah-Hartman // SPDX-License-Identifier: GPL-2.0 21da177e4SLinus Torvalds /* 31da177e4SLinus Torvalds * Precise Delay Loops for SuperH 41da177e4SLinus Torvalds * 51da177e4SLinus Torvalds * Copyright (C) 1999 Niibe Yutaka & Kaz Kojima 61da177e4SLinus Torvalds */ 71da177e4SLinus Torvalds 81da177e4SLinus Torvalds #include <linux/sched.h> 91da177e4SLinus Torvalds #include <linux/delay.h> 101da177e4SLinus Torvalds __delay(unsigned long loops)111da177e4SLinus Torvaldsvoid __delay(unsigned long loops) 121da177e4SLinus Torvalds { 131da177e4SLinus Torvalds __asm__ __volatile__( 14a0865368SStuart Menefy /* 15a0865368SStuart Menefy * ST40-300 appears to have an issue with this code, 16a0865368SStuart Menefy * normally taking two cycles each loop, as with all 17a0865368SStuart Menefy * other SH variants. If however the branch and the 18a0865368SStuart Menefy * delay slot straddle an 8 byte boundary, this increases 19a0865368SStuart Menefy * to 3 cycles. 20a0865368SStuart Menefy * This align directive ensures this doesn't occur. 21a0865368SStuart Menefy */ 22a0865368SStuart Menefy ".balign 8\n\t" 23a0865368SStuart Menefy 241da177e4SLinus Torvalds "tst %0, %0\n\t" 251da177e4SLinus Torvalds "1:\t" 261da177e4SLinus Torvalds "bf/s 1b\n\t" 271da177e4SLinus Torvalds " dt %0" 281da177e4SLinus Torvalds : "=r" (loops) 291da177e4SLinus Torvalds : "0" (loops) 301da177e4SLinus Torvalds : "t"); 311da177e4SLinus Torvalds } 321da177e4SLinus Torvalds __const_udelay(unsigned long xloops)331da177e4SLinus Torvaldsinline void __const_udelay(unsigned long xloops) 341da177e4SLinus Torvalds { 35bd4fb4d4SStuart Menefy xloops *= 4; 361da177e4SLinus Torvalds __asm__("dmulu.l %0, %2\n\t" 371da177e4SLinus Torvalds "sts mach, %0" 381da177e4SLinus Torvalds : "=r" (xloops) 39c71861e6Skogiidena : "0" (xloops), 40bd4fb4d4SStuart Menefy "r" (cpu_data[raw_smp_processor_id()].loops_per_jiffy * (HZ/4)) 411da177e4SLinus Torvalds : "macl", "mach"); 42bd4fb4d4SStuart Menefy __delay(++xloops); 431da177e4SLinus Torvalds } 441da177e4SLinus Torvalds __udelay(unsigned long usecs)451da177e4SLinus Torvaldsvoid __udelay(unsigned long usecs) 461da177e4SLinus Torvalds { 471da177e4SLinus Torvalds __const_udelay(usecs * 0x000010c6); /* 2**32 / 1000000 */ 481da177e4SLinus Torvalds } 491da177e4SLinus Torvalds __ndelay(unsigned long nsecs)501da177e4SLinus Torvaldsvoid __ndelay(unsigned long nsecs) 511da177e4SLinus Torvalds { 521da177e4SLinus Torvalds __const_udelay(nsecs * 0x00000005); 531da177e4SLinus Torvalds } 541da177e4SLinus Torvalds 55