xref: /OK3568_Linux_fs/kernel/drivers/clocksource/mxs_timer.c (revision 4882a59341e53eb6f0b4789bf948001014eff981)
1*4882a593Smuzhiyun // SPDX-License-Identifier: GPL-2.0+
2*4882a593Smuzhiyun //
3*4882a593Smuzhiyun //  Copyright (C) 2000-2001 Deep Blue Solutions
4*4882a593Smuzhiyun //  Copyright (C) 2002 Shane Nay (shane@minirl.com)
5*4882a593Smuzhiyun //  Copyright (C) 2006-2007 Pavel Pisa (ppisa@pikron.com)
6*4882a593Smuzhiyun //  Copyright (C) 2008 Juergen Beisert (kernel@pengutronix.de)
7*4882a593Smuzhiyun //  Copyright (C) 2010 Freescale Semiconductor, Inc. All Rights Reserved.
8*4882a593Smuzhiyun 
9*4882a593Smuzhiyun #include <linux/err.h>
10*4882a593Smuzhiyun #include <linux/interrupt.h>
11*4882a593Smuzhiyun #include <linux/irq.h>
12*4882a593Smuzhiyun #include <linux/clockchips.h>
13*4882a593Smuzhiyun #include <linux/clk.h>
14*4882a593Smuzhiyun #include <linux/of.h>
15*4882a593Smuzhiyun #include <linux/of_address.h>
16*4882a593Smuzhiyun #include <linux/of_irq.h>
17*4882a593Smuzhiyun #include <linux/stmp_device.h>
18*4882a593Smuzhiyun #include <linux/sched_clock.h>
19*4882a593Smuzhiyun 
20*4882a593Smuzhiyun /*
21*4882a593Smuzhiyun  * There are 2 versions of the timrot on Freescale MXS-based SoCs.
22*4882a593Smuzhiyun  * The v1 on MX23 only gets 16 bits counter, while v2 on MX28
23*4882a593Smuzhiyun  * extends the counter to 32 bits.
24*4882a593Smuzhiyun  *
25*4882a593Smuzhiyun  * The implementation uses two timers, one for clock_event and
26*4882a593Smuzhiyun  * another for clocksource. MX28 uses timrot 0 and 1, while MX23
27*4882a593Smuzhiyun  * uses 0 and 2.
28*4882a593Smuzhiyun  */
29*4882a593Smuzhiyun 
30*4882a593Smuzhiyun #define MX23_TIMROT_VERSION_OFFSET	0x0a0
31*4882a593Smuzhiyun #define MX28_TIMROT_VERSION_OFFSET	0x120
32*4882a593Smuzhiyun #define BP_TIMROT_MAJOR_VERSION		24
33*4882a593Smuzhiyun #define BV_TIMROT_VERSION_1		0x01
34*4882a593Smuzhiyun #define BV_TIMROT_VERSION_2		0x02
35*4882a593Smuzhiyun #define timrot_is_v1()	(timrot_major_version == BV_TIMROT_VERSION_1)
36*4882a593Smuzhiyun 
37*4882a593Smuzhiyun /*
38*4882a593Smuzhiyun  * There are 4 registers for each timrotv2 instance, and 2 registers
39*4882a593Smuzhiyun  * for each timrotv1. So address step 0x40 in macros below strides
40*4882a593Smuzhiyun  * one instance of timrotv2 while two instances of timrotv1.
41*4882a593Smuzhiyun  *
42*4882a593Smuzhiyun  * As the result, HW_TIMROT_XXXn(1) defines the address of timrot1
43*4882a593Smuzhiyun  * on MX28 while timrot2 on MX23.
44*4882a593Smuzhiyun  */
45*4882a593Smuzhiyun /* common between v1 and v2 */
46*4882a593Smuzhiyun #define HW_TIMROT_ROTCTRL		0x00
47*4882a593Smuzhiyun #define HW_TIMROT_TIMCTRLn(n)		(0x20 + (n) * 0x40)
48*4882a593Smuzhiyun /* v1 only */
49*4882a593Smuzhiyun #define HW_TIMROT_TIMCOUNTn(n)		(0x30 + (n) * 0x40)
50*4882a593Smuzhiyun /* v2 only */
51*4882a593Smuzhiyun #define HW_TIMROT_RUNNING_COUNTn(n)	(0x30 + (n) * 0x40)
52*4882a593Smuzhiyun #define HW_TIMROT_FIXED_COUNTn(n)	(0x40 + (n) * 0x40)
53*4882a593Smuzhiyun 
54*4882a593Smuzhiyun #define BM_TIMROT_TIMCTRLn_RELOAD	(1 << 6)
55*4882a593Smuzhiyun #define BM_TIMROT_TIMCTRLn_UPDATE	(1 << 7)
56*4882a593Smuzhiyun #define BM_TIMROT_TIMCTRLn_IRQ_EN	(1 << 14)
57*4882a593Smuzhiyun #define BM_TIMROT_TIMCTRLn_IRQ		(1 << 15)
58*4882a593Smuzhiyun #define BP_TIMROT_TIMCTRLn_SELECT	0
59*4882a593Smuzhiyun #define BV_TIMROTv1_TIMCTRLn_SELECT__32KHZ_XTAL		0x8
60*4882a593Smuzhiyun #define BV_TIMROTv2_TIMCTRLn_SELECT__32KHZ_XTAL		0xb
61*4882a593Smuzhiyun #define BV_TIMROTv2_TIMCTRLn_SELECT__TICK_ALWAYS	0xf
62*4882a593Smuzhiyun 
63*4882a593Smuzhiyun static struct clock_event_device mxs_clockevent_device;
64*4882a593Smuzhiyun 
65*4882a593Smuzhiyun static void __iomem *mxs_timrot_base;
66*4882a593Smuzhiyun static u32 timrot_major_version;
67*4882a593Smuzhiyun 
timrot_irq_disable(void)68*4882a593Smuzhiyun static inline void timrot_irq_disable(void)
69*4882a593Smuzhiyun {
70*4882a593Smuzhiyun 	__raw_writel(BM_TIMROT_TIMCTRLn_IRQ_EN, mxs_timrot_base +
71*4882a593Smuzhiyun 		     HW_TIMROT_TIMCTRLn(0) + STMP_OFFSET_REG_CLR);
72*4882a593Smuzhiyun }
73*4882a593Smuzhiyun 
timrot_irq_enable(void)74*4882a593Smuzhiyun static inline void timrot_irq_enable(void)
75*4882a593Smuzhiyun {
76*4882a593Smuzhiyun 	__raw_writel(BM_TIMROT_TIMCTRLn_IRQ_EN, mxs_timrot_base +
77*4882a593Smuzhiyun 		     HW_TIMROT_TIMCTRLn(0) + STMP_OFFSET_REG_SET);
78*4882a593Smuzhiyun }
79*4882a593Smuzhiyun 
timrot_irq_acknowledge(void)80*4882a593Smuzhiyun static void timrot_irq_acknowledge(void)
81*4882a593Smuzhiyun {
82*4882a593Smuzhiyun 	__raw_writel(BM_TIMROT_TIMCTRLn_IRQ, mxs_timrot_base +
83*4882a593Smuzhiyun 		     HW_TIMROT_TIMCTRLn(0) + STMP_OFFSET_REG_CLR);
84*4882a593Smuzhiyun }
85*4882a593Smuzhiyun 
timrotv1_get_cycles(struct clocksource * cs)86*4882a593Smuzhiyun static u64 timrotv1_get_cycles(struct clocksource *cs)
87*4882a593Smuzhiyun {
88*4882a593Smuzhiyun 	return ~((__raw_readl(mxs_timrot_base + HW_TIMROT_TIMCOUNTn(1))
89*4882a593Smuzhiyun 			& 0xffff0000) >> 16);
90*4882a593Smuzhiyun }
91*4882a593Smuzhiyun 
timrotv1_set_next_event(unsigned long evt,struct clock_event_device * dev)92*4882a593Smuzhiyun static int timrotv1_set_next_event(unsigned long evt,
93*4882a593Smuzhiyun 					struct clock_event_device *dev)
94*4882a593Smuzhiyun {
95*4882a593Smuzhiyun 	/* timrot decrements the count */
96*4882a593Smuzhiyun 	__raw_writel(evt, mxs_timrot_base + HW_TIMROT_TIMCOUNTn(0));
97*4882a593Smuzhiyun 
98*4882a593Smuzhiyun 	return 0;
99*4882a593Smuzhiyun }
100*4882a593Smuzhiyun 
timrotv2_set_next_event(unsigned long evt,struct clock_event_device * dev)101*4882a593Smuzhiyun static int timrotv2_set_next_event(unsigned long evt,
102*4882a593Smuzhiyun 					struct clock_event_device *dev)
103*4882a593Smuzhiyun {
104*4882a593Smuzhiyun 	/* timrot decrements the count */
105*4882a593Smuzhiyun 	__raw_writel(evt, mxs_timrot_base + HW_TIMROT_FIXED_COUNTn(0));
106*4882a593Smuzhiyun 
107*4882a593Smuzhiyun 	return 0;
108*4882a593Smuzhiyun }
109*4882a593Smuzhiyun 
mxs_timer_interrupt(int irq,void * dev_id)110*4882a593Smuzhiyun static irqreturn_t mxs_timer_interrupt(int irq, void *dev_id)
111*4882a593Smuzhiyun {
112*4882a593Smuzhiyun 	struct clock_event_device *evt = dev_id;
113*4882a593Smuzhiyun 
114*4882a593Smuzhiyun 	timrot_irq_acknowledge();
115*4882a593Smuzhiyun 	evt->event_handler(evt);
116*4882a593Smuzhiyun 
117*4882a593Smuzhiyun 	return IRQ_HANDLED;
118*4882a593Smuzhiyun }
119*4882a593Smuzhiyun 
mxs_irq_clear(char * state)120*4882a593Smuzhiyun static void mxs_irq_clear(char *state)
121*4882a593Smuzhiyun {
122*4882a593Smuzhiyun 	/* Disable interrupt in timer module */
123*4882a593Smuzhiyun 	timrot_irq_disable();
124*4882a593Smuzhiyun 
125*4882a593Smuzhiyun 	/* Set event time into the furthest future */
126*4882a593Smuzhiyun 	if (timrot_is_v1())
127*4882a593Smuzhiyun 		__raw_writel(0xffff, mxs_timrot_base + HW_TIMROT_TIMCOUNTn(1));
128*4882a593Smuzhiyun 	else
129*4882a593Smuzhiyun 		__raw_writel(0xffffffff,
130*4882a593Smuzhiyun 			     mxs_timrot_base + HW_TIMROT_FIXED_COUNTn(1));
131*4882a593Smuzhiyun 
132*4882a593Smuzhiyun 	/* Clear pending interrupt */
133*4882a593Smuzhiyun 	timrot_irq_acknowledge();
134*4882a593Smuzhiyun 	pr_debug("%s: changing mode to %s\n", __func__, state);
135*4882a593Smuzhiyun }
136*4882a593Smuzhiyun 
mxs_shutdown(struct clock_event_device * evt)137*4882a593Smuzhiyun static int mxs_shutdown(struct clock_event_device *evt)
138*4882a593Smuzhiyun {
139*4882a593Smuzhiyun 	mxs_irq_clear("shutdown");
140*4882a593Smuzhiyun 
141*4882a593Smuzhiyun 	return 0;
142*4882a593Smuzhiyun }
143*4882a593Smuzhiyun 
mxs_set_oneshot(struct clock_event_device * evt)144*4882a593Smuzhiyun static int mxs_set_oneshot(struct clock_event_device *evt)
145*4882a593Smuzhiyun {
146*4882a593Smuzhiyun 	if (clockevent_state_oneshot(evt))
147*4882a593Smuzhiyun 		mxs_irq_clear("oneshot");
148*4882a593Smuzhiyun 	timrot_irq_enable();
149*4882a593Smuzhiyun 	return 0;
150*4882a593Smuzhiyun }
151*4882a593Smuzhiyun 
152*4882a593Smuzhiyun static struct clock_event_device mxs_clockevent_device = {
153*4882a593Smuzhiyun 	.name			= "mxs_timrot",
154*4882a593Smuzhiyun 	.features		= CLOCK_EVT_FEAT_ONESHOT,
155*4882a593Smuzhiyun 	.set_state_shutdown	= mxs_shutdown,
156*4882a593Smuzhiyun 	.set_state_oneshot	= mxs_set_oneshot,
157*4882a593Smuzhiyun 	.tick_resume		= mxs_shutdown,
158*4882a593Smuzhiyun 	.set_next_event		= timrotv2_set_next_event,
159*4882a593Smuzhiyun 	.rating			= 200,
160*4882a593Smuzhiyun };
161*4882a593Smuzhiyun 
mxs_clockevent_init(struct clk * timer_clk)162*4882a593Smuzhiyun static int __init mxs_clockevent_init(struct clk *timer_clk)
163*4882a593Smuzhiyun {
164*4882a593Smuzhiyun 	if (timrot_is_v1())
165*4882a593Smuzhiyun 		mxs_clockevent_device.set_next_event = timrotv1_set_next_event;
166*4882a593Smuzhiyun 	mxs_clockevent_device.cpumask = cpumask_of(0);
167*4882a593Smuzhiyun 	clockevents_config_and_register(&mxs_clockevent_device,
168*4882a593Smuzhiyun 					clk_get_rate(timer_clk),
169*4882a593Smuzhiyun 					timrot_is_v1() ? 0xf : 0x2,
170*4882a593Smuzhiyun 					timrot_is_v1() ? 0xfffe : 0xfffffffe);
171*4882a593Smuzhiyun 
172*4882a593Smuzhiyun 	return 0;
173*4882a593Smuzhiyun }
174*4882a593Smuzhiyun 
175*4882a593Smuzhiyun static struct clocksource clocksource_mxs = {
176*4882a593Smuzhiyun 	.name		= "mxs_timer",
177*4882a593Smuzhiyun 	.rating		= 200,
178*4882a593Smuzhiyun 	.read		= timrotv1_get_cycles,
179*4882a593Smuzhiyun 	.mask		= CLOCKSOURCE_MASK(16),
180*4882a593Smuzhiyun 	.flags		= CLOCK_SOURCE_IS_CONTINUOUS,
181*4882a593Smuzhiyun };
182*4882a593Smuzhiyun 
mxs_read_sched_clock_v2(void)183*4882a593Smuzhiyun static u64 notrace mxs_read_sched_clock_v2(void)
184*4882a593Smuzhiyun {
185*4882a593Smuzhiyun 	return ~readl_relaxed(mxs_timrot_base + HW_TIMROT_RUNNING_COUNTn(1));
186*4882a593Smuzhiyun }
187*4882a593Smuzhiyun 
mxs_clocksource_init(struct clk * timer_clk)188*4882a593Smuzhiyun static int __init mxs_clocksource_init(struct clk *timer_clk)
189*4882a593Smuzhiyun {
190*4882a593Smuzhiyun 	unsigned int c = clk_get_rate(timer_clk);
191*4882a593Smuzhiyun 
192*4882a593Smuzhiyun 	if (timrot_is_v1())
193*4882a593Smuzhiyun 		clocksource_register_hz(&clocksource_mxs, c);
194*4882a593Smuzhiyun 	else {
195*4882a593Smuzhiyun 		clocksource_mmio_init(mxs_timrot_base + HW_TIMROT_RUNNING_COUNTn(1),
196*4882a593Smuzhiyun 			"mxs_timer", c, 200, 32, clocksource_mmio_readl_down);
197*4882a593Smuzhiyun 		sched_clock_register(mxs_read_sched_clock_v2, 32, c);
198*4882a593Smuzhiyun 	}
199*4882a593Smuzhiyun 
200*4882a593Smuzhiyun 	return 0;
201*4882a593Smuzhiyun }
202*4882a593Smuzhiyun 
mxs_timer_init(struct device_node * np)203*4882a593Smuzhiyun static int __init mxs_timer_init(struct device_node *np)
204*4882a593Smuzhiyun {
205*4882a593Smuzhiyun 	struct clk *timer_clk;
206*4882a593Smuzhiyun 	int irq, ret;
207*4882a593Smuzhiyun 
208*4882a593Smuzhiyun 	mxs_timrot_base = of_iomap(np, 0);
209*4882a593Smuzhiyun 	WARN_ON(!mxs_timrot_base);
210*4882a593Smuzhiyun 
211*4882a593Smuzhiyun 	timer_clk = of_clk_get(np, 0);
212*4882a593Smuzhiyun 	if (IS_ERR(timer_clk)) {
213*4882a593Smuzhiyun 		pr_err("%s: failed to get clk\n", __func__);
214*4882a593Smuzhiyun 		return PTR_ERR(timer_clk);
215*4882a593Smuzhiyun 	}
216*4882a593Smuzhiyun 
217*4882a593Smuzhiyun 	ret = clk_prepare_enable(timer_clk);
218*4882a593Smuzhiyun 	if (ret)
219*4882a593Smuzhiyun 		return ret;
220*4882a593Smuzhiyun 
221*4882a593Smuzhiyun 	/*
222*4882a593Smuzhiyun 	 * Initialize timers to a known state
223*4882a593Smuzhiyun 	 */
224*4882a593Smuzhiyun 	stmp_reset_block(mxs_timrot_base + HW_TIMROT_ROTCTRL);
225*4882a593Smuzhiyun 
226*4882a593Smuzhiyun 	/* get timrot version */
227*4882a593Smuzhiyun 	timrot_major_version = __raw_readl(mxs_timrot_base +
228*4882a593Smuzhiyun 			(of_device_is_compatible(np, "fsl,imx23-timrot") ?
229*4882a593Smuzhiyun 						MX23_TIMROT_VERSION_OFFSET :
230*4882a593Smuzhiyun 						MX28_TIMROT_VERSION_OFFSET));
231*4882a593Smuzhiyun 	timrot_major_version >>= BP_TIMROT_MAJOR_VERSION;
232*4882a593Smuzhiyun 
233*4882a593Smuzhiyun 	/* one for clock_event */
234*4882a593Smuzhiyun 	__raw_writel((timrot_is_v1() ?
235*4882a593Smuzhiyun 			BV_TIMROTv1_TIMCTRLn_SELECT__32KHZ_XTAL :
236*4882a593Smuzhiyun 			BV_TIMROTv2_TIMCTRLn_SELECT__TICK_ALWAYS) |
237*4882a593Smuzhiyun 			BM_TIMROT_TIMCTRLn_UPDATE |
238*4882a593Smuzhiyun 			BM_TIMROT_TIMCTRLn_IRQ_EN,
239*4882a593Smuzhiyun 			mxs_timrot_base + HW_TIMROT_TIMCTRLn(0));
240*4882a593Smuzhiyun 
241*4882a593Smuzhiyun 	/* another for clocksource */
242*4882a593Smuzhiyun 	__raw_writel((timrot_is_v1() ?
243*4882a593Smuzhiyun 			BV_TIMROTv1_TIMCTRLn_SELECT__32KHZ_XTAL :
244*4882a593Smuzhiyun 			BV_TIMROTv2_TIMCTRLn_SELECT__TICK_ALWAYS) |
245*4882a593Smuzhiyun 			BM_TIMROT_TIMCTRLn_RELOAD,
246*4882a593Smuzhiyun 			mxs_timrot_base + HW_TIMROT_TIMCTRLn(1));
247*4882a593Smuzhiyun 
248*4882a593Smuzhiyun 	/* set clocksource timer fixed count to the maximum */
249*4882a593Smuzhiyun 	if (timrot_is_v1())
250*4882a593Smuzhiyun 		__raw_writel(0xffff,
251*4882a593Smuzhiyun 			mxs_timrot_base + HW_TIMROT_TIMCOUNTn(1));
252*4882a593Smuzhiyun 	else
253*4882a593Smuzhiyun 		__raw_writel(0xffffffff,
254*4882a593Smuzhiyun 			mxs_timrot_base + HW_TIMROT_FIXED_COUNTn(1));
255*4882a593Smuzhiyun 
256*4882a593Smuzhiyun 	/* init and register the timer to the framework */
257*4882a593Smuzhiyun 	ret = mxs_clocksource_init(timer_clk);
258*4882a593Smuzhiyun 	if (ret)
259*4882a593Smuzhiyun 		return ret;
260*4882a593Smuzhiyun 
261*4882a593Smuzhiyun 	ret = mxs_clockevent_init(timer_clk);
262*4882a593Smuzhiyun 	if (ret)
263*4882a593Smuzhiyun 		return ret;
264*4882a593Smuzhiyun 
265*4882a593Smuzhiyun 	/* Make irqs happen */
266*4882a593Smuzhiyun 	irq = irq_of_parse_and_map(np, 0);
267*4882a593Smuzhiyun 	if (irq <= 0)
268*4882a593Smuzhiyun 		return -EINVAL;
269*4882a593Smuzhiyun 
270*4882a593Smuzhiyun 	return request_irq(irq, mxs_timer_interrupt, IRQF_TIMER | IRQF_IRQPOLL,
271*4882a593Smuzhiyun 			   "MXS Timer Tick", &mxs_clockevent_device);
272*4882a593Smuzhiyun }
273*4882a593Smuzhiyun TIMER_OF_DECLARE(mxs, "fsl,timrot", mxs_timer_init);
274