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 Chenstatic 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 Chenstatic 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