xref: /openbmc/linux/arch/loongarch/include/asm/time.h (revision 366bb35a)
1b738c106SHuacai Chen /* SPDX-License-Identifier: GPL-2.0 */
2b738c106SHuacai Chen /*
3b738c106SHuacai Chen  * Copyright (C) 2020-2022 Loongson Technology Corporation Limited
4b738c106SHuacai Chen  */
5b738c106SHuacai Chen #ifndef _ASM_TIME_H
6b738c106SHuacai Chen #define _ASM_TIME_H
7b738c106SHuacai Chen 
8b738c106SHuacai Chen #include <linux/clockchips.h>
9b738c106SHuacai Chen #include <linux/clocksource.h>
10b738c106SHuacai Chen #include <asm/loongarch.h>
11b738c106SHuacai Chen 
12b738c106SHuacai Chen extern u64 cpu_clock_freq;
13b738c106SHuacai Chen extern u64 const_clock_freq;
14b738c106SHuacai Chen 
15*366bb35aSHuacai Chen extern void save_counter(void);
16b738c106SHuacai Chen extern void sync_counter(void);
17b738c106SHuacai Chen 
calc_const_freq(void)18b738c106SHuacai Chen static inline unsigned int calc_const_freq(void)
19b738c106SHuacai Chen {
20b738c106SHuacai Chen 	unsigned int res;
21b738c106SHuacai Chen 	unsigned int base_freq;
22b738c106SHuacai Chen 	unsigned int cfm, cfd;
23b738c106SHuacai Chen 
24b738c106SHuacai Chen 	res = read_cpucfg(LOONGARCH_CPUCFG2);
25b738c106SHuacai Chen 	if (!(res & CPUCFG2_LLFTP))
26b738c106SHuacai Chen 		return 0;
27b738c106SHuacai Chen 
28b738c106SHuacai Chen 	base_freq = read_cpucfg(LOONGARCH_CPUCFG4);
29b738c106SHuacai Chen 	res = read_cpucfg(LOONGARCH_CPUCFG5);
30b738c106SHuacai Chen 	cfm = res & 0xffff;
31b738c106SHuacai Chen 	cfd = (res >> 16) & 0xffff;
32b738c106SHuacai Chen 
33b738c106SHuacai Chen 	if (!base_freq || !cfm || !cfd)
34b738c106SHuacai Chen 		return 0;
35b738c106SHuacai Chen 
36b738c106SHuacai Chen 	return (base_freq * cfm / cfd);
37b738c106SHuacai Chen }
38b738c106SHuacai Chen 
39b738c106SHuacai Chen /*
40b738c106SHuacai Chen  * Initialize the calling CPU's timer interrupt as clockevent device
41b738c106SHuacai Chen  */
42b738c106SHuacai Chen extern int constant_clockevent_init(void);
43b738c106SHuacai Chen extern int constant_clocksource_init(void);
44b738c106SHuacai Chen 
clockevent_set_clock(struct clock_event_device * cd,unsigned int clock)45b738c106SHuacai Chen static inline void clockevent_set_clock(struct clock_event_device *cd,
46b738c106SHuacai Chen 					unsigned int clock)
47b738c106SHuacai Chen {
48b738c106SHuacai Chen 	clockevents_calc_mult_shift(cd, clock, 4);
49b738c106SHuacai Chen }
50b738c106SHuacai Chen 
51b738c106SHuacai Chen #endif /* _ASM_TIME_H */
52