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