linux/arch/arm64/lib/delay.c
<<
>>
Prefs
   1// SPDX-License-Identifier: GPL-2.0-only
   2/*
   3 * Delay loops based on the OpenRISC implementation.
   4 *
   5 * Copyright (C) 2012 ARM Limited
   6 *
   7 * Author: Will Deacon <will.deacon@arm.com>
   8 */
   9
  10#include <linux/delay.h>
  11#include <linux/init.h>
  12#include <linux/kernel.h>
  13#include <linux/module.h>
  14#include <linux/timex.h>
  15
  16#include <clocksource/arm_arch_timer.h>
  17
  18#define USECS_TO_CYCLES(time_usecs)                     \
  19        xloops_to_cycles((time_usecs) * 0x10C7UL)
  20
  21static inline unsigned long xloops_to_cycles(unsigned long xloops)
  22{
  23        return (xloops * loops_per_jiffy * HZ) >> 32;
  24}
  25
  26void __delay(unsigned long cycles)
  27{
  28        cycles_t start = get_cycles();
  29
  30        if (arch_timer_evtstrm_available()) {
  31                const cycles_t timer_evt_period =
  32                        USECS_TO_CYCLES(ARCH_TIMER_EVT_STREAM_PERIOD_US);
  33
  34                while ((get_cycles() - start + timer_evt_period) < cycles)
  35                        wfe();
  36        }
  37
  38        while ((get_cycles() - start) < cycles)
  39                cpu_relax();
  40}
  41EXPORT_SYMBOL(__delay);
  42
  43inline void __const_udelay(unsigned long xloops)
  44{
  45        __delay(xloops_to_cycles(xloops));
  46}
  47EXPORT_SYMBOL(__const_udelay);
  48
  49void __udelay(unsigned long usecs)
  50{
  51        __const_udelay(usecs * 0x10C7UL); /* 2**32 / 1000000 (rounded up) */
  52}
  53EXPORT_SYMBOL(__udelay);
  54
  55void __ndelay(unsigned long nsecs)
  56{
  57        __const_udelay(nsecs * 0x5UL); /* 2**32 / 1000000000 (rounded up) */
  58}
  59EXPORT_SYMBOL(__ndelay);
  60