xref: /openbmc/linux/arch/riscv/include/asm/timex.h (revision 2612e3bbc0386368a850140a6c9b990cd496a5ec)
150acfb2bSThomas Gleixner /* SPDX-License-Identifier: GPL-2.0-only */
26d60b6eeSPalmer Dabbelt /*
36d60b6eeSPalmer Dabbelt  * Copyright (C) 2012 Regents of the University of California
46d60b6eeSPalmer Dabbelt  */
56d60b6eeSPalmer Dabbelt 
66d60b6eeSPalmer Dabbelt #ifndef _ASM_RISCV_TIMEX_H
76d60b6eeSPalmer Dabbelt #define _ASM_RISCV_TIMEX_H
86d60b6eeSPalmer Dabbelt 
92f12dbf1SChristoph Hellwig #include <asm/csr.h>
106d60b6eeSPalmer Dabbelt 
116d60b6eeSPalmer Dabbelt typedef unsigned long cycles_t;
126d60b6eeSPalmer Dabbelt 
13d5be89a8SPalmer Dabbelt #ifdef CONFIG_RISCV_M_MODE
14d5be89a8SPalmer Dabbelt 
15d5be89a8SPalmer Dabbelt #include <asm/clint.h>
16d5be89a8SPalmer Dabbelt 
17d5be89a8SPalmer Dabbelt #ifdef CONFIG_64BIT
get_cycles(void)18d5be89a8SPalmer Dabbelt static inline cycles_t get_cycles(void)
19d5be89a8SPalmer Dabbelt {
20d5be89a8SPalmer Dabbelt 	return readq_relaxed(clint_time_val);
21d5be89a8SPalmer Dabbelt }
22d5be89a8SPalmer Dabbelt #else /* !CONFIG_64BIT */
get_cycles(void)23d5be89a8SPalmer Dabbelt static inline u32 get_cycles(void)
24d5be89a8SPalmer Dabbelt {
25d5be89a8SPalmer Dabbelt 	return readl_relaxed(((u32 *)clint_time_val));
26d5be89a8SPalmer Dabbelt }
27d5be89a8SPalmer Dabbelt #define get_cycles get_cycles
28d5be89a8SPalmer Dabbelt 
get_cycles_hi(void)29d5be89a8SPalmer Dabbelt static inline u32 get_cycles_hi(void)
30d5be89a8SPalmer Dabbelt {
31d5be89a8SPalmer Dabbelt 	return readl_relaxed(((u32 *)clint_time_val) + 1);
32d5be89a8SPalmer Dabbelt }
33d5be89a8SPalmer Dabbelt #define get_cycles_hi get_cycles_hi
34d5be89a8SPalmer Dabbelt #endif /* CONFIG_64BIT */
35d5be89a8SPalmer Dabbelt 
36aa988760SAnup Patel /*
37aa988760SAnup Patel  * Much like MIPS, we may not have a viable counter to use at an early point
38aa988760SAnup Patel  * in the boot process. Unfortunately we don't have a fallback, so instead
39aa988760SAnup Patel  * we just return 0.
40aa988760SAnup Patel  */
random_get_entropy(void)41aa988760SAnup Patel static inline unsigned long random_get_entropy(void)
42aa988760SAnup Patel {
43aa988760SAnup Patel 	if (unlikely(clint_time_val == NULL))
44*6d012386SJason A. Donenfeld 		return random_get_entropy_fallback();
45aa988760SAnup Patel 	return get_cycles();
46aa988760SAnup Patel }
47aa988760SAnup Patel #define random_get_entropy()	random_get_entropy()
48aa988760SAnup Patel 
49d5be89a8SPalmer Dabbelt #else /* CONFIG_RISCV_M_MODE */
50d5be89a8SPalmer Dabbelt 
get_cycles(void)512f12dbf1SChristoph Hellwig static inline cycles_t get_cycles(void)
526d60b6eeSPalmer Dabbelt {
532f12dbf1SChristoph Hellwig 	return csr_read(CSR_TIME);
546d60b6eeSPalmer Dabbelt }
552f12dbf1SChristoph Hellwig #define get_cycles get_cycles
566d60b6eeSPalmer Dabbelt 
get_cycles_hi(void)572bc3fc87SAnup Patel static inline u32 get_cycles_hi(void)
582bc3fc87SAnup Patel {
592bc3fc87SAnup Patel 	return csr_read(CSR_TIMEH);
602bc3fc87SAnup Patel }
612bc3fc87SAnup Patel #define get_cycles_hi get_cycles_hi
622bc3fc87SAnup Patel 
63ccbbfd1cSPalmer Dabbelt #endif /* !CONFIG_RISCV_M_MODE */
64ccbbfd1cSPalmer Dabbelt 
656d60b6eeSPalmer Dabbelt #ifdef CONFIG_64BIT
get_cycles64(void)662f12dbf1SChristoph Hellwig static inline u64 get_cycles64(void)
676d60b6eeSPalmer Dabbelt {
686d60b6eeSPalmer Dabbelt 	return get_cycles();
696d60b6eeSPalmer Dabbelt }
702f12dbf1SChristoph Hellwig #else /* CONFIG_64BIT */
get_cycles64(void)712f12dbf1SChristoph Hellwig static inline u64 get_cycles64(void)
722f12dbf1SChristoph Hellwig {
732f12dbf1SChristoph Hellwig 	u32 hi, lo;
742f12dbf1SChristoph Hellwig 
752f12dbf1SChristoph Hellwig 	do {
762f12dbf1SChristoph Hellwig 		hi = get_cycles_hi();
772f12dbf1SChristoph Hellwig 		lo = get_cycles();
782f12dbf1SChristoph Hellwig 	} while (hi != get_cycles_hi());
792f12dbf1SChristoph Hellwig 
806d60b6eeSPalmer Dabbelt 	return ((u64)hi << 32) | lo;
816d60b6eeSPalmer Dabbelt }
822f12dbf1SChristoph Hellwig #endif /* CONFIG_64BIT */
836d60b6eeSPalmer Dabbelt 
846d60b6eeSPalmer Dabbelt #define ARCH_HAS_READ_CURRENT_TIMER
read_current_timer(unsigned long * timer_val)856d60b6eeSPalmer Dabbelt static inline int read_current_timer(unsigned long *timer_val)
866d60b6eeSPalmer Dabbelt {
876d60b6eeSPalmer Dabbelt 	*timer_val = get_cycles();
886d60b6eeSPalmer Dabbelt 	return 0;
896d60b6eeSPalmer Dabbelt }
906d60b6eeSPalmer Dabbelt 
916d60b6eeSPalmer Dabbelt #endif /* _ASM_RISCV_TIMEX_H */
92