linux/arch/sh/lib/delay.c
<<
>>
Prefs
   1// SPDX-License-Identifier: GPL-2.0
   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
  11void __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
  33inline 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
  45void __udelay(unsigned long usecs)
  46{
  47        __const_udelay(usecs * 0x000010c6);  /* 2**32 / 1000000 */
  48}
  49
  50void __ndelay(unsigned long nsecs)
  51{
  52        __const_udelay(nsecs * 0x00000005);
  53}
  54
  55