1 /* SPDX-License-Identifier: GPL-2.0-only */ 2 /* 3 * Copyright (C) 2012 Regents of the University of California 4 */ 5 6 #ifndef _ASM_RISCV_TIMEX_H 7 #define _ASM_RISCV_TIMEX_H 8 9 #include <asm/csr.h> 10 11 typedef unsigned long cycles_t; 12 13 #ifdef CONFIG_RISCV_M_MODE 14 15 #include <asm/clint.h> 16 17 #ifdef CONFIG_64BIT get_cycles(void)18static inline cycles_t get_cycles(void) 19 { 20 return readq_relaxed(clint_time_val); 21 } 22 #else /* !CONFIG_64BIT */ get_cycles(void)23static inline u32 get_cycles(void) 24 { 25 return readl_relaxed(((u32 *)clint_time_val)); 26 } 27 #define get_cycles get_cycles 28 get_cycles_hi(void)29static inline u32 get_cycles_hi(void) 30 { 31 return readl_relaxed(((u32 *)clint_time_val) + 1); 32 } 33 #define get_cycles_hi get_cycles_hi 34 #endif /* CONFIG_64BIT */ 35 36 /* 37 * Much like MIPS, we may not have a viable counter to use at an early point 38 * in the boot process. Unfortunately we don't have a fallback, so instead 39 * we just return 0. 40 */ random_get_entropy(void)41static inline unsigned long random_get_entropy(void) 42 { 43 if (unlikely(clint_time_val == NULL)) 44 return random_get_entropy_fallback(); 45 return get_cycles(); 46 } 47 #define random_get_entropy() random_get_entropy() 48 49 #else /* CONFIG_RISCV_M_MODE */ 50 get_cycles(void)51static inline cycles_t get_cycles(void) 52 { 53 return csr_read(CSR_TIME); 54 } 55 #define get_cycles get_cycles 56 get_cycles_hi(void)57static inline u32 get_cycles_hi(void) 58 { 59 return csr_read(CSR_TIMEH); 60 } 61 #define get_cycles_hi get_cycles_hi 62 63 #endif /* !CONFIG_RISCV_M_MODE */ 64 65 #ifdef CONFIG_64BIT get_cycles64(void)66static inline u64 get_cycles64(void) 67 { 68 return get_cycles(); 69 } 70 #else /* CONFIG_64BIT */ get_cycles64(void)71static inline u64 get_cycles64(void) 72 { 73 u32 hi, lo; 74 75 do { 76 hi = get_cycles_hi(); 77 lo = get_cycles(); 78 } while (hi != get_cycles_hi()); 79 80 return ((u64)hi << 32) | lo; 81 } 82 #endif /* CONFIG_64BIT */ 83 84 #define ARCH_HAS_READ_CURRENT_TIMER read_current_timer(unsigned long * timer_val)85static inline int read_current_timer(unsigned long *timer_val) 86 { 87 *timer_val = get_cycles(); 88 return 0; 89 } 90 91 #endif /* _ASM_RISCV_TIMEX_H */ 92