xref: /OK3568_Linux_fs/kernel/drivers/clocksource/timer-keystone.c (revision 4882a59341e53eb6f0b4789bf948001014eff981)
1*4882a593Smuzhiyun // SPDX-License-Identifier: GPL-2.0-only
2*4882a593Smuzhiyun /*
3*4882a593Smuzhiyun  * Keystone broadcast clock-event
4*4882a593Smuzhiyun  *
5*4882a593Smuzhiyun  * Copyright 2013 Texas Instruments, Inc.
6*4882a593Smuzhiyun  *
7*4882a593Smuzhiyun  * Author: Ivan Khoronzhuk <ivan.khoronzhuk@ti.com>
8*4882a593Smuzhiyun  */
9*4882a593Smuzhiyun 
10*4882a593Smuzhiyun #include <linux/clk.h>
11*4882a593Smuzhiyun #include <linux/clockchips.h>
12*4882a593Smuzhiyun #include <linux/clocksource.h>
13*4882a593Smuzhiyun #include <linux/interrupt.h>
14*4882a593Smuzhiyun #include <linux/of_address.h>
15*4882a593Smuzhiyun #include <linux/of_irq.h>
16*4882a593Smuzhiyun 
17*4882a593Smuzhiyun #define TIMER_NAME			"timer-keystone"
18*4882a593Smuzhiyun 
19*4882a593Smuzhiyun /* Timer register offsets */
20*4882a593Smuzhiyun #define TIM12				0x10
21*4882a593Smuzhiyun #define TIM34				0x14
22*4882a593Smuzhiyun #define PRD12				0x18
23*4882a593Smuzhiyun #define PRD34				0x1c
24*4882a593Smuzhiyun #define TCR				0x20
25*4882a593Smuzhiyun #define TGCR				0x24
26*4882a593Smuzhiyun #define INTCTLSTAT			0x44
27*4882a593Smuzhiyun 
28*4882a593Smuzhiyun /* Timer register bitfields */
29*4882a593Smuzhiyun #define TCR_ENAMODE_MASK		0xC0
30*4882a593Smuzhiyun #define TCR_ENAMODE_ONESHOT_MASK	0x40
31*4882a593Smuzhiyun #define TCR_ENAMODE_PERIODIC_MASK	0x80
32*4882a593Smuzhiyun 
33*4882a593Smuzhiyun #define TGCR_TIM_UNRESET_MASK		0x03
34*4882a593Smuzhiyun #define INTCTLSTAT_ENINT_MASK		0x01
35*4882a593Smuzhiyun 
36*4882a593Smuzhiyun /**
37*4882a593Smuzhiyun  * struct keystone_timer: holds timer's data
38*4882a593Smuzhiyun  * @base: timer memory base address
39*4882a593Smuzhiyun  * @hz_period: cycles per HZ period
40*4882a593Smuzhiyun  * @event_dev: event device based on timer
41*4882a593Smuzhiyun  */
42*4882a593Smuzhiyun static struct keystone_timer {
43*4882a593Smuzhiyun 	void __iomem *base;
44*4882a593Smuzhiyun 	unsigned long hz_period;
45*4882a593Smuzhiyun 	struct clock_event_device event_dev;
46*4882a593Smuzhiyun } timer;
47*4882a593Smuzhiyun 
keystone_timer_readl(unsigned long rg)48*4882a593Smuzhiyun static inline u32 keystone_timer_readl(unsigned long rg)
49*4882a593Smuzhiyun {
50*4882a593Smuzhiyun 	return readl_relaxed(timer.base + rg);
51*4882a593Smuzhiyun }
52*4882a593Smuzhiyun 
keystone_timer_writel(u32 val,unsigned long rg)53*4882a593Smuzhiyun static inline void keystone_timer_writel(u32 val, unsigned long rg)
54*4882a593Smuzhiyun {
55*4882a593Smuzhiyun 	writel_relaxed(val, timer.base + rg);
56*4882a593Smuzhiyun }
57*4882a593Smuzhiyun 
58*4882a593Smuzhiyun /**
59*4882a593Smuzhiyun  * keystone_timer_barrier: write memory barrier
60*4882a593Smuzhiyun  * use explicit barrier to avoid using readl/writel non relaxed function
61*4882a593Smuzhiyun  * variants, because in our case non relaxed variants hide the true places
62*4882a593Smuzhiyun  * where barrier is needed.
63*4882a593Smuzhiyun  */
keystone_timer_barrier(void)64*4882a593Smuzhiyun static inline void keystone_timer_barrier(void)
65*4882a593Smuzhiyun {
66*4882a593Smuzhiyun 	__iowmb();
67*4882a593Smuzhiyun }
68*4882a593Smuzhiyun 
69*4882a593Smuzhiyun /**
70*4882a593Smuzhiyun  * keystone_timer_config: configures timer to work in oneshot/periodic modes.
71*4882a593Smuzhiyun  * @ mask: mask of the mode to configure
72*4882a593Smuzhiyun  * @ period: cycles number to configure for
73*4882a593Smuzhiyun  */
keystone_timer_config(u64 period,int mask)74*4882a593Smuzhiyun static int keystone_timer_config(u64 period, int mask)
75*4882a593Smuzhiyun {
76*4882a593Smuzhiyun 	u32 tcr;
77*4882a593Smuzhiyun 	u32 off;
78*4882a593Smuzhiyun 
79*4882a593Smuzhiyun 	tcr = keystone_timer_readl(TCR);
80*4882a593Smuzhiyun 	off = tcr & ~(TCR_ENAMODE_MASK);
81*4882a593Smuzhiyun 
82*4882a593Smuzhiyun 	/* set enable mode */
83*4882a593Smuzhiyun 	tcr |= mask;
84*4882a593Smuzhiyun 
85*4882a593Smuzhiyun 	/* disable timer */
86*4882a593Smuzhiyun 	keystone_timer_writel(off, TCR);
87*4882a593Smuzhiyun 	/* here we have to be sure the timer has been disabled */
88*4882a593Smuzhiyun 	keystone_timer_barrier();
89*4882a593Smuzhiyun 
90*4882a593Smuzhiyun 	/* reset counter to zero, set new period */
91*4882a593Smuzhiyun 	keystone_timer_writel(0, TIM12);
92*4882a593Smuzhiyun 	keystone_timer_writel(0, TIM34);
93*4882a593Smuzhiyun 	keystone_timer_writel(period & 0xffffffff, PRD12);
94*4882a593Smuzhiyun 	keystone_timer_writel(period >> 32, PRD34);
95*4882a593Smuzhiyun 
96*4882a593Smuzhiyun 	/*
97*4882a593Smuzhiyun 	 * enable timer
98*4882a593Smuzhiyun 	 * here we have to be sure that CNTLO, CNTHI, PRDLO, PRDHI registers
99*4882a593Smuzhiyun 	 * have been written.
100*4882a593Smuzhiyun 	 */
101*4882a593Smuzhiyun 	keystone_timer_barrier();
102*4882a593Smuzhiyun 	keystone_timer_writel(tcr, TCR);
103*4882a593Smuzhiyun 	return 0;
104*4882a593Smuzhiyun }
105*4882a593Smuzhiyun 
keystone_timer_disable(void)106*4882a593Smuzhiyun static void keystone_timer_disable(void)
107*4882a593Smuzhiyun {
108*4882a593Smuzhiyun 	u32 tcr;
109*4882a593Smuzhiyun 
110*4882a593Smuzhiyun 	tcr = keystone_timer_readl(TCR);
111*4882a593Smuzhiyun 
112*4882a593Smuzhiyun 	/* disable timer */
113*4882a593Smuzhiyun 	tcr &= ~(TCR_ENAMODE_MASK);
114*4882a593Smuzhiyun 	keystone_timer_writel(tcr, TCR);
115*4882a593Smuzhiyun }
116*4882a593Smuzhiyun 
keystone_timer_interrupt(int irq,void * dev_id)117*4882a593Smuzhiyun static irqreturn_t keystone_timer_interrupt(int irq, void *dev_id)
118*4882a593Smuzhiyun {
119*4882a593Smuzhiyun 	struct clock_event_device *evt = dev_id;
120*4882a593Smuzhiyun 
121*4882a593Smuzhiyun 	evt->event_handler(evt);
122*4882a593Smuzhiyun 	return IRQ_HANDLED;
123*4882a593Smuzhiyun }
124*4882a593Smuzhiyun 
keystone_set_next_event(unsigned long cycles,struct clock_event_device * evt)125*4882a593Smuzhiyun static int keystone_set_next_event(unsigned long cycles,
126*4882a593Smuzhiyun 				  struct clock_event_device *evt)
127*4882a593Smuzhiyun {
128*4882a593Smuzhiyun 	return keystone_timer_config(cycles, TCR_ENAMODE_ONESHOT_MASK);
129*4882a593Smuzhiyun }
130*4882a593Smuzhiyun 
keystone_shutdown(struct clock_event_device * evt)131*4882a593Smuzhiyun static int keystone_shutdown(struct clock_event_device *evt)
132*4882a593Smuzhiyun {
133*4882a593Smuzhiyun 	keystone_timer_disable();
134*4882a593Smuzhiyun 	return 0;
135*4882a593Smuzhiyun }
136*4882a593Smuzhiyun 
keystone_set_periodic(struct clock_event_device * evt)137*4882a593Smuzhiyun static int keystone_set_periodic(struct clock_event_device *evt)
138*4882a593Smuzhiyun {
139*4882a593Smuzhiyun 	keystone_timer_config(timer.hz_period, TCR_ENAMODE_PERIODIC_MASK);
140*4882a593Smuzhiyun 	return 0;
141*4882a593Smuzhiyun }
142*4882a593Smuzhiyun 
keystone_timer_init(struct device_node * np)143*4882a593Smuzhiyun static int __init keystone_timer_init(struct device_node *np)
144*4882a593Smuzhiyun {
145*4882a593Smuzhiyun 	struct clock_event_device *event_dev = &timer.event_dev;
146*4882a593Smuzhiyun 	unsigned long rate;
147*4882a593Smuzhiyun 	struct clk *clk;
148*4882a593Smuzhiyun 	int irq, error;
149*4882a593Smuzhiyun 
150*4882a593Smuzhiyun 	irq  = irq_of_parse_and_map(np, 0);
151*4882a593Smuzhiyun 	if (!irq) {
152*4882a593Smuzhiyun 		pr_err("%s: failed to map interrupts\n", __func__);
153*4882a593Smuzhiyun 		return -EINVAL;
154*4882a593Smuzhiyun 	}
155*4882a593Smuzhiyun 
156*4882a593Smuzhiyun 	timer.base = of_iomap(np, 0);
157*4882a593Smuzhiyun 	if (!timer.base) {
158*4882a593Smuzhiyun 		pr_err("%s: failed to map registers\n", __func__);
159*4882a593Smuzhiyun 		return -ENXIO;
160*4882a593Smuzhiyun 	}
161*4882a593Smuzhiyun 
162*4882a593Smuzhiyun 	clk = of_clk_get(np, 0);
163*4882a593Smuzhiyun 	if (IS_ERR(clk)) {
164*4882a593Smuzhiyun 		pr_err("%s: failed to get clock\n", __func__);
165*4882a593Smuzhiyun 		iounmap(timer.base);
166*4882a593Smuzhiyun 		return PTR_ERR(clk);
167*4882a593Smuzhiyun 	}
168*4882a593Smuzhiyun 
169*4882a593Smuzhiyun 	error = clk_prepare_enable(clk);
170*4882a593Smuzhiyun 	if (error) {
171*4882a593Smuzhiyun 		pr_err("%s: failed to enable clock\n", __func__);
172*4882a593Smuzhiyun 		goto err;
173*4882a593Smuzhiyun 	}
174*4882a593Smuzhiyun 
175*4882a593Smuzhiyun 	rate = clk_get_rate(clk);
176*4882a593Smuzhiyun 
177*4882a593Smuzhiyun 	/* disable, use internal clock source */
178*4882a593Smuzhiyun 	keystone_timer_writel(0, TCR);
179*4882a593Smuzhiyun 	/* here we have to be sure the timer has been disabled */
180*4882a593Smuzhiyun 	keystone_timer_barrier();
181*4882a593Smuzhiyun 
182*4882a593Smuzhiyun 	/* reset timer as 64-bit, no pre-scaler, plus features are disabled */
183*4882a593Smuzhiyun 	keystone_timer_writel(0, TGCR);
184*4882a593Smuzhiyun 
185*4882a593Smuzhiyun 	/* unreset timer */
186*4882a593Smuzhiyun 	keystone_timer_writel(TGCR_TIM_UNRESET_MASK, TGCR);
187*4882a593Smuzhiyun 
188*4882a593Smuzhiyun 	/* init counter to zero */
189*4882a593Smuzhiyun 	keystone_timer_writel(0, TIM12);
190*4882a593Smuzhiyun 	keystone_timer_writel(0, TIM34);
191*4882a593Smuzhiyun 
192*4882a593Smuzhiyun 	timer.hz_period = DIV_ROUND_UP(rate, HZ);
193*4882a593Smuzhiyun 
194*4882a593Smuzhiyun 	/* enable timer interrupts */
195*4882a593Smuzhiyun 	keystone_timer_writel(INTCTLSTAT_ENINT_MASK, INTCTLSTAT);
196*4882a593Smuzhiyun 
197*4882a593Smuzhiyun 	error = request_irq(irq, keystone_timer_interrupt, IRQF_TIMER,
198*4882a593Smuzhiyun 			    TIMER_NAME, event_dev);
199*4882a593Smuzhiyun 	if (error) {
200*4882a593Smuzhiyun 		pr_err("%s: failed to setup irq\n", __func__);
201*4882a593Smuzhiyun 		goto err;
202*4882a593Smuzhiyun 	}
203*4882a593Smuzhiyun 
204*4882a593Smuzhiyun 	/* setup clockevent */
205*4882a593Smuzhiyun 	event_dev->features = CLOCK_EVT_FEAT_PERIODIC | CLOCK_EVT_FEAT_ONESHOT;
206*4882a593Smuzhiyun 	event_dev->set_next_event = keystone_set_next_event;
207*4882a593Smuzhiyun 	event_dev->set_state_shutdown = keystone_shutdown;
208*4882a593Smuzhiyun 	event_dev->set_state_periodic = keystone_set_periodic;
209*4882a593Smuzhiyun 	event_dev->set_state_oneshot = keystone_shutdown;
210*4882a593Smuzhiyun 	event_dev->cpumask = cpu_possible_mask;
211*4882a593Smuzhiyun 	event_dev->owner = THIS_MODULE;
212*4882a593Smuzhiyun 	event_dev->name = TIMER_NAME;
213*4882a593Smuzhiyun 	event_dev->irq = irq;
214*4882a593Smuzhiyun 
215*4882a593Smuzhiyun 	clockevents_config_and_register(event_dev, rate, 1, ULONG_MAX);
216*4882a593Smuzhiyun 
217*4882a593Smuzhiyun 	pr_info("keystone timer clock @%lu Hz\n", rate);
218*4882a593Smuzhiyun 	return 0;
219*4882a593Smuzhiyun err:
220*4882a593Smuzhiyun 	clk_put(clk);
221*4882a593Smuzhiyun 	iounmap(timer.base);
222*4882a593Smuzhiyun 	return error;
223*4882a593Smuzhiyun }
224*4882a593Smuzhiyun 
225*4882a593Smuzhiyun TIMER_OF_DECLARE(keystone_timer, "ti,keystone-timer",
226*4882a593Smuzhiyun 			   keystone_timer_init);
227