| 1 | |
| 2 | |
| 3 | * Precise Delay Loops for SuperH
|
| 4 | *
|
| 5 | * Copyright (C) 1999 Niibe Yutaka & Kaz Kojima
|
| 6 |
|
| 7 |
|
| 8 | #include <linux/sched.h>
|
| 9 | #include <linux/delay.h>
|
| 10 |
|
| 11 | void __delay(unsigned long loops)
|
| 12 | {
|
| 13 | __asm__ __volatile__(
|
| 14 | |
| 15 | * ST40-300 appears to have an issue with this code,
|
| 16 | * normally taking two cycles each loop, as with all
|
| 17 | * other SH variants. If however the branch and the
|
| 18 | * delay slot straddle an 8 byte boundary, this increases
|
| 19 | * to 3 cycles.
|
| 20 | * This align directive ensures this doesn't occur.
|
| 21 |
|
| 22 | ".balign 8\n\t"
|
| 23 |
|
| 24 | "tst %0, %0\n\t"
|
| 25 | "1:\t"
|
| 26 | "bf/s 1b\n\t"
|
| 27 | " dt %0"
|
| 28 | : "=r" (loops)
|
| 29 | : "0" (loops)
|
| 30 | : "t");
|
| 31 | }
|
| 32 |
|
| 33 | inline void __const_udelay(unsigned long xloops)
|
| 34 | {
|
| 35 | xloops *= 4;
|
| 36 | __asm__("dmulu.l %0, %2\n\t"
|
| 37 | "sts mach, %0"
|
| 38 | : "=r" (xloops)
|
| 39 | : "0" (xloops),
|
| 40 | "r" (cpu_data[raw_smp_processor_id()].loops_per_jiffy * (HZ/4))
|
| 41 | : "macl", "mach");
|
| 42 | __delay(++xloops);
|
| 43 | }
|
| 44 |
|
| 45 | void __udelay(unsigned long usecs)
|
| 46 | {
|
| 47 | __const_udelay(usecs * 0x000010c6);
|
| 48 | }
|
| 49 |
|
| 50 | void __ndelay(unsigned long nsecs)
|
| 51 | {
|
| 52 | __const_udelay(nsecs * 0x00000005);
|
| 53 | }
|
| 54 |
|