root/arch/riscv/lib/delay.c

/* [<][>][^][v][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. __delay
  2. udelay
  3. ndelay

   1 // SPDX-License-Identifier: GPL-2.0-only
   2 /*
   3  * Copyright (C) 2012 Regents of the University of California
   4  */
   5 
   6 #include <linux/delay.h>
   7 #include <linux/param.h>
   8 #include <linux/timex.h>
   9 #include <linux/export.h>
  10 
  11 /*
  12  * This is copies from arch/arm/include/asm/delay.h
  13  *
  14  * Loop (or tick) based delay:
  15  *
  16  * loops = loops_per_jiffy * jiffies_per_sec * delay_us / us_per_sec
  17  *
  18  * where:
  19  *
  20  * jiffies_per_sec = HZ
  21  * us_per_sec = 1000000
  22  *
  23  * Therefore the constant part is HZ / 1000000 which is a small
  24  * fractional number. To make this usable with integer math, we
  25  * scale up this constant by 2^31, perform the actual multiplication,
  26  * and scale the result back down by 2^31 with a simple shift:
  27  *
  28  * loops = (loops_per_jiffy * delay_us * UDELAY_MULT) >> 31
  29  *
  30  * where:
  31  *
  32  * UDELAY_MULT = 2^31 * HZ / 1000000
  33  *             = (2^31 / 1000000) * HZ
  34  *             = 2147.483648 * HZ
  35  *             = 2147 * HZ + 483648 * HZ / 1000000
  36  *
  37  * 31 is the biggest scale shift value that won't overflow 32 bits for
  38  * delay_us * UDELAY_MULT assuming HZ <= 1000 and delay_us <= 2000.
  39  */
  40 #define MAX_UDELAY_US   2000
  41 #define MAX_UDELAY_HZ   1000
  42 #define UDELAY_MULT     (2147UL * HZ + 483648UL * HZ / 1000000UL)
  43 #define UDELAY_SHIFT    31
  44 
  45 #if HZ > MAX_UDELAY_HZ
  46 #error "HZ > MAX_UDELAY_HZ"
  47 #endif
  48 
  49 /*
  50  * RISC-V supports both UDELAY and NDELAY.  This is largely the same as above,
  51  * but with different constants.  I added 10 bits to the shift to get this, but
  52  * the result is that I need a 64-bit multiply, which is slow on 32-bit
  53  * platforms.
  54  *
  55  * NDELAY_MULT = 2^41 * HZ / 1000000000
  56  *             = (2^41 / 1000000000) * HZ
  57  *             = 2199.02325555 * HZ
  58  *             = 2199 * HZ + 23255550 * HZ / 1000000000
  59  *
  60  * The maximum here is to avoid 64-bit overflow, but it isn't checked as it
  61  * won't happen.
  62  */
  63 #define MAX_NDELAY_NS   (1ULL << 42)
  64 #define MAX_NDELAY_HZ   MAX_UDELAY_HZ
  65 #define NDELAY_MULT     ((unsigned long long)(2199ULL * HZ + 23255550ULL * HZ / 1000000000ULL))
  66 #define NDELAY_SHIFT    41
  67 
  68 #if HZ > MAX_NDELAY_HZ
  69 #error "HZ > MAX_NDELAY_HZ"
  70 #endif
  71 
  72 void __delay(unsigned long cycles)
  73 {
  74         u64 t0 = get_cycles();
  75 
  76         while ((unsigned long)(get_cycles() - t0) < cycles)
  77                 cpu_relax();
  78 }
  79 EXPORT_SYMBOL(__delay);
  80 
  81 void udelay(unsigned long usecs)
  82 {
  83         u64 ucycles = (u64)usecs * lpj_fine * UDELAY_MULT;
  84         u64 n;
  85 
  86         if (unlikely(usecs > MAX_UDELAY_US)) {
  87                 n = (u64)usecs * riscv_timebase;
  88                 do_div(n, 1000000);
  89 
  90                 __delay(n);
  91                 return;
  92         }
  93 
  94         __delay(ucycles >> UDELAY_SHIFT);
  95 }
  96 EXPORT_SYMBOL(udelay);
  97 
  98 void ndelay(unsigned long nsecs)
  99 {
 100         /*
 101          * This doesn't bother checking for overflow, as it won't happen (it's
 102          * an hour) of delay.
 103          */
 104         unsigned long long ncycles = nsecs * lpj_fine * NDELAY_MULT;
 105         __delay(ncycles >> NDELAY_SHIFT);
 106 }
 107 EXPORT_SYMBOL(ndelay);

/* [<][>][^][v][top][bottom][index][help] */