1 /* SPDX-License-Identifier: GPL-2.0 */
2 /*
3  * Copyright (C) 2020 Loongson Technology Corporation Limited
4  *
5  * This program is free software; you can redistribute	it and/or modify it
6  * under  the terms of	the GNU General	 Public License as published by the
7  * Free Software Foundation;  either version 2 of the  License, or (at your
8  * option) any later version.
9  */
10 #ifndef _ASM_TIME_H
11 #define _ASM_TIME_H
12 
13 #include <linux/clockchips.h>
14 #include <linux/clocksource.h>
15 #include <asm/loongarchregs.h>
16 
17 extern u64 cpu_clock_freq;
18 extern u64 const_clock_freq;
19 
20 extern void save_counter(void);
21 extern void sync_counter(void);
22 
calc_const_freq(void)23 static inline unsigned int calc_const_freq(void)
24 {
25 	unsigned int res;
26 	unsigned int base_freq;
27 	unsigned int cfm, cfd;
28 
29 	res = read_cpucfg(LOONGARCH_CPUCFG2);
30 	if (!(res & CPUCFG2_LLFTP))
31 		return 0;
32 
33 	base_freq = read_cpucfg(LOONGARCH_CPUCFG4);
34 	res = read_cpucfg(LOONGARCH_CPUCFG5);
35 	cfm = res & 0xffff;
36 	cfd = (res >> 16) & 0xffff;
37 
38 	if (!base_freq || !cfm || !cfd)
39 		return 0;
40 
41 	return (base_freq * cfm / cfd);
42 }
43 
44 /*
45  * Initialize the calling CPU's timer interrupt as clockevent device
46  */
47 extern int constant_clockevent_init(void);
48 extern int constant_clocksource_init(void);
49 
clockevent_set_clock(struct clock_event_device *cd, unsigned int clock)50 static inline void clockevent_set_clock(struct clock_event_device *cd,
51 					unsigned int clock)
52 {
53 	clockevents_calc_mult_shift(cd, clock, 4);
54 }
55 
56 #endif /* _ASM_TIME_H */
57