18c2ecf20Sopenharmony_ci// SPDX-License-Identifier: GPL-2.0-only 28c2ecf20Sopenharmony_ci/* 38c2ecf20Sopenharmony_ci * Copyright (C) 2011 Richard Weinberger <richrd@nod.at> 48c2ecf20Sopenharmony_ci * Mostly copied from arch/x86/lib/delay.c 58c2ecf20Sopenharmony_ci */ 68c2ecf20Sopenharmony_ci 78c2ecf20Sopenharmony_ci#include <linux/export.h> 88c2ecf20Sopenharmony_ci#include <linux/kernel.h> 98c2ecf20Sopenharmony_ci#include <linux/delay.h> 108c2ecf20Sopenharmony_ci#include <asm/param.h> 118c2ecf20Sopenharmony_ci 128c2ecf20Sopenharmony_civoid __delay(unsigned long loops) 138c2ecf20Sopenharmony_ci{ 148c2ecf20Sopenharmony_ci asm volatile( 158c2ecf20Sopenharmony_ci "test %0,%0\n" 168c2ecf20Sopenharmony_ci "jz 3f\n" 178c2ecf20Sopenharmony_ci "jmp 1f\n" 188c2ecf20Sopenharmony_ci 198c2ecf20Sopenharmony_ci ".align 16\n" 208c2ecf20Sopenharmony_ci "1: jmp 2f\n" 218c2ecf20Sopenharmony_ci 228c2ecf20Sopenharmony_ci ".align 16\n" 238c2ecf20Sopenharmony_ci "2: dec %0\n" 248c2ecf20Sopenharmony_ci " jnz 2b\n" 258c2ecf20Sopenharmony_ci "3: dec %0\n" 268c2ecf20Sopenharmony_ci 278c2ecf20Sopenharmony_ci : /* we don't need output */ 288c2ecf20Sopenharmony_ci : "a" (loops) 298c2ecf20Sopenharmony_ci ); 308c2ecf20Sopenharmony_ci} 318c2ecf20Sopenharmony_ciEXPORT_SYMBOL(__delay); 328c2ecf20Sopenharmony_ci 338c2ecf20Sopenharmony_ciinline void __const_udelay(unsigned long xloops) 348c2ecf20Sopenharmony_ci{ 358c2ecf20Sopenharmony_ci int d0; 368c2ecf20Sopenharmony_ci 378c2ecf20Sopenharmony_ci xloops *= 4; 388c2ecf20Sopenharmony_ci asm("mull %%edx" 398c2ecf20Sopenharmony_ci : "=d" (xloops), "=&a" (d0) 408c2ecf20Sopenharmony_ci : "1" (xloops), "0" 418c2ecf20Sopenharmony_ci (loops_per_jiffy * (HZ/4))); 428c2ecf20Sopenharmony_ci 438c2ecf20Sopenharmony_ci __delay(++xloops); 448c2ecf20Sopenharmony_ci} 458c2ecf20Sopenharmony_ciEXPORT_SYMBOL(__const_udelay); 468c2ecf20Sopenharmony_ci 478c2ecf20Sopenharmony_civoid __udelay(unsigned long usecs) 488c2ecf20Sopenharmony_ci{ 498c2ecf20Sopenharmony_ci __const_udelay(usecs * 0x000010c7); /* 2**32 / 1000000 (rounded up) */ 508c2ecf20Sopenharmony_ci} 518c2ecf20Sopenharmony_ciEXPORT_SYMBOL(__udelay); 528c2ecf20Sopenharmony_ci 538c2ecf20Sopenharmony_civoid __ndelay(unsigned long nsecs) 548c2ecf20Sopenharmony_ci{ 558c2ecf20Sopenharmony_ci __const_udelay(nsecs * 0x00005); /* 2**32 / 1000000000 (rounded up) */ 568c2ecf20Sopenharmony_ci} 578c2ecf20Sopenharmony_ciEXPORT_SYMBOL(__ndelay); 58