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(cs: &clocksource_dec); |
44 | |
45 | while (i--) |
46 | while (!ds1287_timer_state()) |
47 | ; |
48 | |
49 | end = dec_ioasic_hpt_read(cs: &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(cs: &clocksource_dec, hz: freq); |
61 | |
62 | sched_clock_register(read: dec_ioasic_read_sched_clock, bits: 32, rate: freq); |
63 | |
64 | return 0; |
65 | } |
66 |