1 // SPDX-License-Identifier: GPL-2.0-or-later 2 /* 3 * DEC I/O ASIC's counter clocksource 4 * 5 * Copyright (C) 2008 Yoichi Yuasa <yuasa@linux-mips.org> 6 */ 7 #include <linux/clocksource.h> 8 #include <linux/sched_clock.h> 9 #include <linux/init.h> 10 11 #include <asm/ds1287.h> 12 #include <asm/time.h> 13 #include <asm/dec/ioasic.h> 14 #include <asm/dec/ioasic_addrs.h> 15 16 static u64 dec_ioasic_hpt_read(struct clocksource *cs) 17 { 18 return ioasic_read(IO_REG_FCTR); 19 } 20 21 static struct clocksource clocksource_dec = { 22 .name = "dec-ioasic", 23 .read = dec_ioasic_hpt_read, 24 .mask = CLOCKSOURCE_MASK(32), 25 .flags = CLOCK_SOURCE_IS_CONTINUOUS, 26 }; 27 28 static u64 notrace dec_ioasic_read_sched_clock(void) 29 { 30 return ioasic_read(IO_REG_FCTR); 31 } 32 33 int __init dec_ioasic_clocksource_init(void) 34 { 35 unsigned int freq; 36 u32 start, end; 37 int i = HZ / 8; 38 39 ds1287_timer_state(); 40 while (!ds1287_timer_state()) 41 ; 42 43 start = dec_ioasic_hpt_read(&clocksource_dec); 44 45 while (i--) 46 while (!ds1287_timer_state()) 47 ; 48 49 end = dec_ioasic_hpt_read(&clocksource_dec); 50 51 freq = (end - start) * 8; 52 53 /* An early revision of the I/O ASIC didn't have the counter. */ 54 if (!freq) 55 return -ENXIO; 56 57 printk(KERN_INFO "I/O ASIC clock frequency %dHz\n", freq); 58 59 clocksource_dec.rating = 200 + freq / 10000000; 60 clocksource_register_hz(&clocksource_dec, freq); 61 62 sched_clock_register(dec_ioasic_read_sched_clock, 32, freq); 63 64 return 0; 65 } 66