1/* 2 * Copyright 2020, Data61, CSIRO (ABN 41 687 119 230) 3 * 4 * SPDX-License-Identifier: GPL-2.0-only 5 */ 6 7#pragma once 8 9#include <config.h> 10#include <stdint.h> 11 12/* convert to khz first to avoid overflow */ 13#define TICKS_PER_MS (TIMER_CLOCK_HZ / HZ_IN_KHZ) 14 15#ifdef CONFIG_KERNEL_MCS 16#include <types.h> 17#include <util.h> 18#include <mode/util.h> 19 20#define USE_KHZ (TIMER_CLOCK_HZ % HZ_IN_MHZ > 0) 21#define TIMER_CLOCK_KHZ (TIMER_CLOCK_HZ / HZ_IN_KHZ) 22#define TIMER_CLOCK_MHZ (TIMER_CLOCK_HZ / HZ_IN_MHZ) 23 24#include <plat/platform_gen.h> 25#include <mode/machine/timer.h> 26 27void initTimer(void); 28 29/* get the max value usToTicks can be passed without overflowing */ 30static inline CONST time_t getMaxUsToTicks(void) 31{ 32#if USE_KHZ 33 return UINT64_MAX / TIMER_CLOCK_KHZ; 34#else 35 return UINT64_MAX / TIMER_CLOCK_MHZ; 36#endif 37} 38 39static inline CONST ticks_t usToTicks(time_t us) 40{ 41#if USE_KHZ 42 /* reciprocal division overflows too quickly for dividing by KHZ_IN_MHZ. 43 * This operation isn't used frequently or on many platforms, so use manual 44 * division here */ 45 return div64(us * TIMER_CLOCK_KHZ, KHZ_IN_MHZ); 46#else 47 return us * TIMER_CLOCK_MHZ; 48#endif 49} 50 51static inline CONST ticks_t getTimerPrecision(void) 52{ 53 return usToTicks(TIMER_PRECISION); 54} 55#else /* CONFIG_KERNEL_MCS */ 56#include <mode/machine/timer.h> 57#include <plat/machine/hardware.h> 58 59#define HZ_IN_KHZ 1000llu 60 61/* but multiply by timer tick ms */ 62#define TIMER_RELOAD (TICKS_PER_MS * CONFIG_TIMER_TICK_MS) 63 64#if (TIMER_RELOAD >= UINTPTR_MAX) 65#error "Timer reload too high" 66#endif 67 68void initTimer(void); 69#endif 70 71