Merge branch 'for-upstream' of git://openrisc.net/jonas/linux
[cascardo/linux.git] / arch / arm / mach-zynq / timer.c
1 /*
2  * This file contains driver for the Xilinx PS Timer Counter IP.
3  *
4  *  Copyright (C) 2011 Xilinx
5  *
6  * based on arch/mips/kernel/time.c timer driver
7  *
8  * This software is licensed under the terms of the GNU General Public
9  * License version 2, as published by the Free Software Foundation, and
10  * may be copied, distributed, and modified under those terms.
11  *
12  * This program is distributed in the hope that it will be useful,
13  * but WITHOUT ANY WARRANTY; without even the implied warranty of
14  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15  * GNU General Public License for more details.
16  */
17
18 #include <linux/interrupt.h>
19 #include <linux/clockchips.h>
20 #include <linux/of_address.h>
21 #include <linux/of_irq.h>
22 #include <linux/slab.h>
23 #include <linux/clk-provider.h>
24 #include "common.h"
25
26 /*
27  * Timer Register Offset Definitions of Timer 1, Increment base address by 4
28  * and use same offsets for Timer 2
29  */
30 #define XTTCPS_CLK_CNTRL_OFFSET         0x00 /* Clock Control Reg, RW */
31 #define XTTCPS_CNT_CNTRL_OFFSET         0x0C /* Counter Control Reg, RW */
32 #define XTTCPS_COUNT_VAL_OFFSET         0x18 /* Counter Value Reg, RO */
33 #define XTTCPS_INTR_VAL_OFFSET          0x24 /* Interval Count Reg, RW */
34 #define XTTCPS_ISR_OFFSET               0x54 /* Interrupt Status Reg, RO */
35 #define XTTCPS_IER_OFFSET               0x60 /* Interrupt Enable Reg, RW */
36
37 #define XTTCPS_CNT_CNTRL_DISABLE_MASK   0x1
38
39 /*
40  * Setup the timers to use pre-scaling, using a fixed value for now that will
41  * work across most input frequency, but it may need to be more dynamic
42  */
43 #define PRESCALE_EXPONENT       11      /* 2 ^ PRESCALE_EXPONENT = PRESCALE */
44 #define PRESCALE                2048    /* The exponent must match this */
45 #define CLK_CNTRL_PRESCALE      ((PRESCALE_EXPONENT - 1) << 1)
46 #define CLK_CNTRL_PRESCALE_EN   1
47 #define CNT_CNTRL_RESET         (1<<4)
48
49 /**
50  * struct xttcps_timer - This definition defines local timer structure
51  *
52  * @base_addr:  Base address of timer
53  **/
54 struct xttcps_timer {
55         void __iomem    *base_addr;
56 };
57
58 struct xttcps_timer_clocksource {
59         struct xttcps_timer     xttc;
60         struct clocksource      cs;
61 };
62
63 #define to_xttcps_timer_clksrc(x) \
64                 container_of(x, struct xttcps_timer_clocksource, cs)
65
66 struct xttcps_timer_clockevent {
67         struct xttcps_timer             xttc;
68         struct clock_event_device       ce;
69         struct clk                      *clk;
70 };
71
72 #define to_xttcps_timer_clkevent(x) \
73                 container_of(x, struct xttcps_timer_clockevent, ce)
74
75 /**
76  * xttcps_set_interval - Set the timer interval value
77  *
78  * @timer:      Pointer to the timer instance
79  * @cycles:     Timer interval ticks
80  **/
81 static void xttcps_set_interval(struct xttcps_timer *timer,
82                                         unsigned long cycles)
83 {
84         u32 ctrl_reg;
85
86         /* Disable the counter, set the counter value  and re-enable counter */
87         ctrl_reg = __raw_readl(timer->base_addr + XTTCPS_CNT_CNTRL_OFFSET);
88         ctrl_reg |= XTTCPS_CNT_CNTRL_DISABLE_MASK;
89         __raw_writel(ctrl_reg, timer->base_addr + XTTCPS_CNT_CNTRL_OFFSET);
90
91         __raw_writel(cycles, timer->base_addr + XTTCPS_INTR_VAL_OFFSET);
92
93         /*
94          * Reset the counter (0x10) so that it starts from 0, one-shot
95          * mode makes this needed for timing to be right.
96          */
97         ctrl_reg |= CNT_CNTRL_RESET;
98         ctrl_reg &= ~XTTCPS_CNT_CNTRL_DISABLE_MASK;
99         __raw_writel(ctrl_reg, timer->base_addr + XTTCPS_CNT_CNTRL_OFFSET);
100 }
101
102 /**
103  * xttcps_clock_event_interrupt - Clock event timer interrupt handler
104  *
105  * @irq:        IRQ number of the Timer
106  * @dev_id:     void pointer to the xttcps_timer instance
107  *
108  * returns: Always IRQ_HANDLED - success
109  **/
110 static irqreturn_t xttcps_clock_event_interrupt(int irq, void *dev_id)
111 {
112         struct xttcps_timer_clockevent *xttce = dev_id;
113         struct xttcps_timer *timer = &xttce->xttc;
114
115         /* Acknowledge the interrupt and call event handler */
116         __raw_readl(timer->base_addr + XTTCPS_ISR_OFFSET);
117
118         xttce->ce.event_handler(&xttce->ce);
119
120         return IRQ_HANDLED;
121 }
122
123 /**
124  * __xttc_clocksource_read - Reads the timer counter register
125  *
126  * returns: Current timer counter register value
127  **/
128 static cycle_t __xttc_clocksource_read(struct clocksource *cs)
129 {
130         struct xttcps_timer *timer = &to_xttcps_timer_clksrc(cs)->xttc;
131
132         return (cycle_t)__raw_readl(timer->base_addr +
133                                 XTTCPS_COUNT_VAL_OFFSET);
134 }
135
136 /**
137  * xttcps_set_next_event - Sets the time interval for next event
138  *
139  * @cycles:     Timer interval ticks
140  * @evt:        Address of clock event instance
141  *
142  * returns: Always 0 - success
143  **/
144 static int xttcps_set_next_event(unsigned long cycles,
145                                         struct clock_event_device *evt)
146 {
147         struct xttcps_timer_clockevent *xttce = to_xttcps_timer_clkevent(evt);
148         struct xttcps_timer *timer = &xttce->xttc;
149
150         xttcps_set_interval(timer, cycles);
151         return 0;
152 }
153
154 /**
155  * xttcps_set_mode - Sets the mode of timer
156  *
157  * @mode:       Mode to be set
158  * @evt:        Address of clock event instance
159  **/
160 static void xttcps_set_mode(enum clock_event_mode mode,
161                                         struct clock_event_device *evt)
162 {
163         struct xttcps_timer_clockevent *xttce = to_xttcps_timer_clkevent(evt);
164         struct xttcps_timer *timer = &xttce->xttc;
165         u32 ctrl_reg;
166
167         switch (mode) {
168         case CLOCK_EVT_MODE_PERIODIC:
169                 xttcps_set_interval(timer,
170                                      DIV_ROUND_CLOSEST(clk_get_rate(xttce->clk),
171                                                        PRESCALE * HZ));
172                 break;
173         case CLOCK_EVT_MODE_ONESHOT:
174         case CLOCK_EVT_MODE_UNUSED:
175         case CLOCK_EVT_MODE_SHUTDOWN:
176                 ctrl_reg = __raw_readl(timer->base_addr +
177                                         XTTCPS_CNT_CNTRL_OFFSET);
178                 ctrl_reg |= XTTCPS_CNT_CNTRL_DISABLE_MASK;
179                 __raw_writel(ctrl_reg,
180                                 timer->base_addr + XTTCPS_CNT_CNTRL_OFFSET);
181                 break;
182         case CLOCK_EVT_MODE_RESUME:
183                 ctrl_reg = __raw_readl(timer->base_addr +
184                                         XTTCPS_CNT_CNTRL_OFFSET);
185                 ctrl_reg &= ~XTTCPS_CNT_CNTRL_DISABLE_MASK;
186                 __raw_writel(ctrl_reg,
187                                 timer->base_addr + XTTCPS_CNT_CNTRL_OFFSET);
188                 break;
189         }
190 }
191
192 static void __init zynq_ttc_setup_clocksource(struct device_node *np,
193                                              void __iomem *base)
194 {
195         struct xttcps_timer_clocksource *ttccs;
196         struct clk *clk;
197         int err;
198         u32 reg;
199
200         ttccs = kzalloc(sizeof(*ttccs), GFP_KERNEL);
201         if (WARN_ON(!ttccs))
202                 return;
203
204         err = of_property_read_u32(np, "reg", &reg);
205         if (WARN_ON(err))
206                 return;
207
208         clk = of_clk_get_by_name(np, "cpu_1x");
209         if (WARN_ON(IS_ERR(clk)))
210                 return;
211
212         err = clk_prepare_enable(clk);
213         if (WARN_ON(err))
214                 return;
215
216         ttccs->xttc.base_addr = base + reg * 4;
217
218         ttccs->cs.name = np->name;
219         ttccs->cs.rating = 200;
220         ttccs->cs.read = __xttc_clocksource_read;
221         ttccs->cs.mask = CLOCKSOURCE_MASK(16);
222         ttccs->cs.flags = CLOCK_SOURCE_IS_CONTINUOUS;
223
224         __raw_writel(0x0,  ttccs->xttc.base_addr + XTTCPS_IER_OFFSET);
225         __raw_writel(CLK_CNTRL_PRESCALE | CLK_CNTRL_PRESCALE_EN,
226                      ttccs->xttc.base_addr + XTTCPS_CLK_CNTRL_OFFSET);
227         __raw_writel(CNT_CNTRL_RESET,
228                      ttccs->xttc.base_addr + XTTCPS_CNT_CNTRL_OFFSET);
229
230         err = clocksource_register_hz(&ttccs->cs, clk_get_rate(clk) / PRESCALE);
231         if (WARN_ON(err))
232                 return;
233 }
234
235 static void __init zynq_ttc_setup_clockevent(struct device_node *np,
236                                             void __iomem *base)
237 {
238         struct xttcps_timer_clockevent *ttcce;
239         int err, irq;
240         u32 reg;
241
242         ttcce = kzalloc(sizeof(*ttcce), GFP_KERNEL);
243         if (WARN_ON(!ttcce))
244                 return;
245
246         err = of_property_read_u32(np, "reg", &reg);
247         if (WARN_ON(err))
248                 return;
249
250         ttcce->xttc.base_addr = base + reg * 4;
251
252         ttcce->clk = of_clk_get_by_name(np, "cpu_1x");
253         if (WARN_ON(IS_ERR(ttcce->clk)))
254                 return;
255
256         err = clk_prepare_enable(ttcce->clk);
257         if (WARN_ON(err))
258                 return;
259
260         irq = irq_of_parse_and_map(np, 0);
261         if (WARN_ON(!irq))
262                 return;
263
264         ttcce->ce.name = np->name;
265         ttcce->ce.features = CLOCK_EVT_FEAT_PERIODIC | CLOCK_EVT_FEAT_ONESHOT;
266         ttcce->ce.set_next_event = xttcps_set_next_event;
267         ttcce->ce.set_mode = xttcps_set_mode;
268         ttcce->ce.rating = 200;
269         ttcce->ce.irq = irq;
270         ttcce->ce.cpumask = cpu_possible_mask;
271
272         __raw_writel(0x23, ttcce->xttc.base_addr + XTTCPS_CNT_CNTRL_OFFSET);
273         __raw_writel(CLK_CNTRL_PRESCALE | CLK_CNTRL_PRESCALE_EN,
274                      ttcce->xttc.base_addr + XTTCPS_CLK_CNTRL_OFFSET);
275         __raw_writel(0x1,  ttcce->xttc.base_addr + XTTCPS_IER_OFFSET);
276
277         err = request_irq(irq, xttcps_clock_event_interrupt, IRQF_TIMER,
278                           np->name, ttcce);
279         if (WARN_ON(err))
280                 return;
281
282         clockevents_config_and_register(&ttcce->ce,
283                                         clk_get_rate(ttcce->clk) / PRESCALE,
284                                         1, 0xfffe);
285 }
286
287 static const __initconst struct of_device_id zynq_ttc_match[] = {
288         { .compatible = "xlnx,ttc-counter-clocksource",
289                 .data = zynq_ttc_setup_clocksource, },
290         { .compatible = "xlnx,ttc-counter-clockevent",
291                 .data = zynq_ttc_setup_clockevent, },
292         {}
293 };
294
295 /**
296  * xttcps_timer_init - Initialize the timer
297  *
298  * Initializes the timer hardware and register the clock source and clock event
299  * timers with Linux kernal timer framework
300  **/
301 void __init xttcps_timer_init(void)
302 {
303         struct device_node *np;
304
305         for_each_compatible_node(np, NULL, "xlnx,ttc") {
306                 struct device_node *np_chld;
307                 void __iomem *base;
308
309                 base = of_iomap(np, 0);
310                 if (WARN_ON(!base))
311                         return;
312
313                 for_each_available_child_of_node(np, np_chld) {
314                         int (*cb)(struct device_node *np, void __iomem *base);
315                         const struct of_device_id *match;
316
317                         match = of_match_node(zynq_ttc_match, np_chld);
318                         if (match) {
319                                 cb = match->data;
320                                 cb(np_chld, base);
321                         }
322                 }
323         }
324 }