162306a36Sopenharmony_ci// SPDX-License-Identifier: GPL-2.0 262306a36Sopenharmony_ci/* 362306a36Sopenharmony_ci * Precise Delay Loops for SuperH 462306a36Sopenharmony_ci * 562306a36Sopenharmony_ci * Copyright (C) 1999 Niibe Yutaka & Kaz Kojima 662306a36Sopenharmony_ci */ 762306a36Sopenharmony_ci 862306a36Sopenharmony_ci#include <linux/sched.h> 962306a36Sopenharmony_ci#include <linux/delay.h> 1062306a36Sopenharmony_ci 1162306a36Sopenharmony_civoid __delay(unsigned long loops) 1262306a36Sopenharmony_ci{ 1362306a36Sopenharmony_ci __asm__ __volatile__( 1462306a36Sopenharmony_ci /* 1562306a36Sopenharmony_ci * ST40-300 appears to have an issue with this code, 1662306a36Sopenharmony_ci * normally taking two cycles each loop, as with all 1762306a36Sopenharmony_ci * other SH variants. If however the branch and the 1862306a36Sopenharmony_ci * delay slot straddle an 8 byte boundary, this increases 1962306a36Sopenharmony_ci * to 3 cycles. 2062306a36Sopenharmony_ci * This align directive ensures this doesn't occur. 2162306a36Sopenharmony_ci */ 2262306a36Sopenharmony_ci ".balign 8\n\t" 2362306a36Sopenharmony_ci 2462306a36Sopenharmony_ci "tst %0, %0\n\t" 2562306a36Sopenharmony_ci "1:\t" 2662306a36Sopenharmony_ci "bf/s 1b\n\t" 2762306a36Sopenharmony_ci " dt %0" 2862306a36Sopenharmony_ci : "=r" (loops) 2962306a36Sopenharmony_ci : "0" (loops) 3062306a36Sopenharmony_ci : "t"); 3162306a36Sopenharmony_ci} 3262306a36Sopenharmony_ci 3362306a36Sopenharmony_ciinline void __const_udelay(unsigned long xloops) 3462306a36Sopenharmony_ci{ 3562306a36Sopenharmony_ci xloops *= 4; 3662306a36Sopenharmony_ci __asm__("dmulu.l %0, %2\n\t" 3762306a36Sopenharmony_ci "sts mach, %0" 3862306a36Sopenharmony_ci : "=r" (xloops) 3962306a36Sopenharmony_ci : "0" (xloops), 4062306a36Sopenharmony_ci "r" (cpu_data[raw_smp_processor_id()].loops_per_jiffy * (HZ/4)) 4162306a36Sopenharmony_ci : "macl", "mach"); 4262306a36Sopenharmony_ci __delay(++xloops); 4362306a36Sopenharmony_ci} 4462306a36Sopenharmony_ci 4562306a36Sopenharmony_civoid __udelay(unsigned long usecs) 4662306a36Sopenharmony_ci{ 4762306a36Sopenharmony_ci __const_udelay(usecs * 0x000010c6); /* 2**32 / 1000000 */ 4862306a36Sopenharmony_ci} 4962306a36Sopenharmony_ci 5062306a36Sopenharmony_civoid __ndelay(unsigned long nsecs) 5162306a36Sopenharmony_ci{ 5262306a36Sopenharmony_ci __const_udelay(nsecs * 0x00000005); 5362306a36Sopenharmony_ci} 5462306a36Sopenharmony_ci 55