xref: /openbmc/linux/arch/mips/kernel/csrc-sb1250.c (revision 75bf465f0bc33e9b776a46d6a1b9b990f5fb7c37)
1*c942fddfSThomas Gleixner // SPDX-License-Identifier: GPL-2.0-or-later
2217dd11eSRalf Baechle /*
3217dd11eSRalf Baechle  * Copyright (C) 2000, 2001 Broadcom Corporation
4217dd11eSRalf Baechle  */
5217dd11eSRalf Baechle #include <linux/clocksource.h>
6262f1c92SDeng-Cheng Zhu #include <linux/sched_clock.h>
7217dd11eSRalf Baechle 
8217dd11eSRalf Baechle #include <asm/addrspace.h>
9217dd11eSRalf Baechle #include <asm/io.h>
10217dd11eSRalf Baechle #include <asm/time.h>
11217dd11eSRalf Baechle 
12217dd11eSRalf Baechle #include <asm/sibyte/sb1250.h>
13217dd11eSRalf Baechle #include <asm/sibyte/sb1250_regs.h>
14217dd11eSRalf Baechle #include <asm/sibyte/sb1250_int.h>
15217dd11eSRalf Baechle #include <asm/sibyte/sb1250_scd.h>
16217dd11eSRalf Baechle 
17217dd11eSRalf Baechle #define SB1250_HPT_NUM		3
18217dd11eSRalf Baechle #define SB1250_HPT_VALUE	M_SCD_TIMER_CNT /* max value */
19217dd11eSRalf Baechle 
20217dd11eSRalf Baechle /*
21217dd11eSRalf Baechle  * The HPT is free running from SB1250_HPT_VALUE down to 0 then starts over
22217dd11eSRalf Baechle  * again.
23217dd11eSRalf Baechle  */
sb1250_hpt_get_cycles(void)24a5a1d1c2SThomas Gleixner static inline u64 sb1250_hpt_get_cycles(void)
25217dd11eSRalf Baechle {
26217dd11eSRalf Baechle 	unsigned int count;
2702710fc8SDeng-Cheng Zhu 	void __iomem *addr;
28217dd11eSRalf Baechle 
2902710fc8SDeng-Cheng Zhu 	addr = IOADDR(A_SCD_TIMER_REGISTER(SB1250_HPT_NUM, R_SCD_TIMER_CNT));
3002710fc8SDeng-Cheng Zhu 	count = G_SCD_TIMER_CNT(__raw_readq(addr));
31217dd11eSRalf Baechle 
32217dd11eSRalf Baechle 	return SB1250_HPT_VALUE - count;
33217dd11eSRalf Baechle }
34217dd11eSRalf Baechle 
sb1250_hpt_read(struct clocksource * cs)35a5a1d1c2SThomas Gleixner static u64 sb1250_hpt_read(struct clocksource *cs)
3602710fc8SDeng-Cheng Zhu {
3702710fc8SDeng-Cheng Zhu 	return sb1250_hpt_get_cycles();
3802710fc8SDeng-Cheng Zhu }
3902710fc8SDeng-Cheng Zhu 
40217dd11eSRalf Baechle struct clocksource bcm1250_clocksource = {
41f99f2cc9SRalf Baechle 	.name	= "bcm1250-counter-3",
42217dd11eSRalf Baechle 	.rating = 200,
43217dd11eSRalf Baechle 	.read	= sb1250_hpt_read,
44217dd11eSRalf Baechle 	.mask	= CLOCKSOURCE_MASK(23),
45217dd11eSRalf Baechle 	.flags	= CLOCK_SOURCE_IS_CONTINUOUS,
46217dd11eSRalf Baechle };
47217dd11eSRalf Baechle 
sb1250_read_sched_clock(void)48262f1c92SDeng-Cheng Zhu static u64 notrace sb1250_read_sched_clock(void)
49262f1c92SDeng-Cheng Zhu {
50262f1c92SDeng-Cheng Zhu 	return sb1250_hpt_get_cycles();
51262f1c92SDeng-Cheng Zhu }
52262f1c92SDeng-Cheng Zhu 
sb1250_clocksource_init(void)53217dd11eSRalf Baechle void __init sb1250_clocksource_init(void)
54217dd11eSRalf Baechle {
55217dd11eSRalf Baechle 	struct clocksource *cs = &bcm1250_clocksource;
56217dd11eSRalf Baechle 
57217dd11eSRalf Baechle 	/* Setup hpt using timer #3 but do not enable irq for it */
58217dd11eSRalf Baechle 	__raw_writeq(0,
59217dd11eSRalf Baechle 		     IOADDR(A_SCD_TIMER_REGISTER(SB1250_HPT_NUM,
60217dd11eSRalf Baechle 						 R_SCD_TIMER_CFG)));
61217dd11eSRalf Baechle 	__raw_writeq(SB1250_HPT_VALUE,
62217dd11eSRalf Baechle 		     IOADDR(A_SCD_TIMER_REGISTER(SB1250_HPT_NUM,
63217dd11eSRalf Baechle 						 R_SCD_TIMER_INIT)));
64217dd11eSRalf Baechle 	__raw_writeq(M_SCD_TIMER_ENABLE | M_SCD_TIMER_MODE_CONTINUOUS,
65217dd11eSRalf Baechle 		     IOADDR(A_SCD_TIMER_REGISTER(SB1250_HPT_NUM,
66217dd11eSRalf Baechle 						 R_SCD_TIMER_CFG)));
67217dd11eSRalf Baechle 
6875c4fd8cSJohn Stultz 	clocksource_register_hz(cs, V_SCD_TIMER_FREQ);
69262f1c92SDeng-Cheng Zhu 
70262f1c92SDeng-Cheng Zhu 	sched_clock_register(sb1250_read_sched_clock, 23, V_SCD_TIMER_FREQ);
71217dd11eSRalf Baechle }
72