ARM: tegra: power: Add TWD context save/restore
[linux-3.10.git] / arch / arm / mach-tegra / timer.c
1 /*
2  * arch/arch/mach-tegra/timer.c
3  *
4  * Copyright (C) 2010 Google, Inc.
5  *
6  * Author:
7  *      Colin Cross <ccross@google.com>
8  *
9  * Copyright (C) 2010-2011 NVIDIA Corporation.
10  *
11  * This software is licensed under the terms of the GNU General Public
12  * License version 2, as published by the Free Software Foundation, and
13  * may be copied, distributed, and modified under those terms.
14  *
15  * This program is distributed in the hope that it will be useful,
16  * but WITHOUT ANY WARRANTY; without even the implied warranty of
17  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
18  * GNU General Public License for more details.
19  *
20  */
21
22 #include <linux/init.h>
23 #include <linux/err.h>
24 #include <linux/time.h>
25 #include <linux/interrupt.h>
26 #include <linux/irq.h>
27 #include <linux/clockchips.h>
28 #include <linux/clocksource.h>
29 #include <linux/clk.h>
30 #include <linux/io.h>
31 #include <linux/syscore_ops.h>
32
33 #include <asm/mach/time.h>
34 #include <asm/delay.h>
35 #include <asm/localtimer.h>
36 #include <asm/smp_twd.h>
37 #include <asm/sched_clock.h>
38
39 #include <mach/irqs.h>
40
41 #include "board.h"
42 #include "clock.h"
43 #include "iomap.h"
44 #include "timer.h"
45
46 static void __iomem *timer_reg_base = IO_ADDRESS(TEGRA_TMR1_BASE);
47 static void __iomem *rtc_base = IO_ADDRESS(TEGRA_RTC_BASE);
48
49 static struct timespec persistent_ts;
50 static u64 persistent_ms, last_persistent_ms;
51 static u32 usec_config;
52 static u32 usec_offset;
53 static bool usec_suspended;
54
55 static u32 system_timer;
56
57 #define timer_writel(value, reg) \
58         __raw_writel(value, timer_reg_base + (reg))
59 #define timer_readl(reg) \
60         __raw_readl(timer_reg_base + (reg))
61
62 static int tegra_timer_set_next_event(unsigned long cycles,
63                                          struct clock_event_device *evt)
64 {
65         u32 reg;
66
67         reg = 0x80000000 | ((cycles > 1) ? (cycles-1) : 0);
68         timer_writel(reg, system_timer + TIMER_PTV);
69
70         return 0;
71 }
72
73 static void tegra_timer_set_mode(enum clock_event_mode mode,
74                                     struct clock_event_device *evt)
75 {
76         u32 reg;
77
78         timer_writel(0, system_timer + TIMER_PTV);
79
80         switch (mode) {
81         case CLOCK_EVT_MODE_PERIODIC:
82                 reg = 0xC0000000 | ((1000000/HZ)-1);
83                 timer_writel(reg, system_timer + TIMER_PTV);
84                 break;
85         case CLOCK_EVT_MODE_ONESHOT:
86                 break;
87         case CLOCK_EVT_MODE_UNUSED:
88         case CLOCK_EVT_MODE_SHUTDOWN:
89         case CLOCK_EVT_MODE_RESUME:
90                 break;
91         }
92 }
93
94 static struct clock_event_device tegra_clockevent = {
95         .name           = "timer0",
96         .rating         = 300,
97         .features       = CLOCK_EVT_FEAT_ONESHOT | CLOCK_EVT_FEAT_PERIODIC,
98         .set_next_event = tegra_timer_set_next_event,
99         .set_mode       = tegra_timer_set_mode,
100 };
101
102 static u32 notrace tegra_read_usec(void)
103 {
104         u32 cyc = usec_offset;
105         if (!usec_suspended)
106                 cyc += timer_readl(TIMERUS_CNTR_1US);
107         return cyc;
108 }
109
110 static u32 notrace tegra_read_sched_clock(void)
111 {
112         return tegra_read_usec();
113 }
114
115 /*
116  * tegra_rtc_read - Reads the Tegra RTC registers
117  * Care must be taken that this funciton is not called while the
118  * tegra_rtc driver could be executing to avoid race conditions
119  * on the RTC shadow register
120  */
121 static u64 tegra_rtc_read_ms(void)
122 {
123         u32 ms = readl(rtc_base + RTC_MILLISECONDS);
124         u32 s = readl(rtc_base + RTC_SHADOW_SECONDS);
125         return (u64)s * MSEC_PER_SEC + ms;
126 }
127
128 /*
129  * tegra_read_persistent_clock -  Return time from a persistent clock.
130  *
131  * Reads the time from a source which isn't disabled during PM, the
132  * 32k sync timer.  Convert the cycles elapsed since last read into
133  * nsecs and adds to a monotonically increasing timespec.
134  * Care must be taken that this funciton is not called while the
135  * tegra_rtc driver could be executing to avoid race conditions
136  * on the RTC shadow register
137  */
138 static void tegra_read_persistent_clock(struct timespec *ts)
139 {
140         u64 delta;
141         struct timespec *tsp = &persistent_ts;
142
143         last_persistent_ms = persistent_ms;
144         persistent_ms = tegra_rtc_read_ms();
145         delta = persistent_ms - last_persistent_ms;
146
147         timespec_add_ns(tsp, delta * NSEC_PER_MSEC);
148         *ts = *tsp;
149 }
150
151 static irqreturn_t tegra_timer_interrupt(int irq, void *dev_id)
152 {
153         struct clock_event_device *evt = (struct clock_event_device *)dev_id;
154         timer_writel(1<<30, system_timer + TIMER_PCR);
155         evt->event_handler(evt);
156         return IRQ_HANDLED;
157 }
158
159 static struct irqaction tegra_timer_irq = {
160         .name           = "timer0",
161         .flags          = IRQF_DISABLED | IRQF_TIMER | IRQF_TRIGGER_HIGH,
162         .handler        = tegra_timer_interrupt,
163         .dev_id         = &tegra_clockevent,
164 };
165
166 static int tegra_timer_suspend(void)
167 {
168         usec_config = timer_readl(TIMERUS_USEC_CFG);
169
170         usec_offset += timer_readl(TIMERUS_CNTR_1US);
171         usec_suspended = true;
172
173         return 0;
174 }
175
176 static void tegra_timer_resume(void)
177 {
178         timer_writel(usec_config, TIMERUS_USEC_CFG);
179
180         usec_offset -= timer_readl(TIMERUS_CNTR_1US);
181         usec_suspended = false;
182 }
183
184 static struct syscore_ops tegra_timer_syscore_ops = {
185         .suspend = tegra_timer_suspend,
186         .resume = tegra_timer_resume,
187 };
188
189 #ifdef CONFIG_HAVE_ARM_TWD
190 static void __iomem *twd_base = IO_ADDRESS(TEGRA_ARM_PERIF_BASE + 0x600);
191 static DEFINE_TWD_LOCAL_TIMER(twd_local_timer,
192                               TEGRA_ARM_PERIF_BASE + 0x600,
193                               IRQ_LOCALTIMER);
194
195 static void __init tegra_twd_init(void)
196 {
197         int err = twd_local_timer_register(&twd_local_timer);
198         if (err)
199                 pr_err("twd_local_timer_register failed %d\n", err);
200 }
201
202 void tegra_twd_suspend(struct tegra_twd_context *context)
203 {
204         context->twd_ctrl = readl(twd_base + TWD_TIMER_CONTROL);
205         context->twd_load = readl(twd_base + TWD_TIMER_LOAD);
206         __raw_writel(0, twd_base + TWD_TIMER_CONTROL);
207 }
208
209 void tegra_twd_resume(struct tegra_twd_context *context)
210 {
211         writel(context->twd_load, twd_base + TWD_TIMER_LOAD);
212         writel(context->twd_ctrl, twd_base + TWD_TIMER_CONTROL);
213 }
214 #else
215 #define tegra_twd_init()        do {} while(0)
216 #endif
217
218 extern void __tegra_delay(unsigned long cycles);
219 extern void __tegra_const_udelay(unsigned long loops);
220 extern void __tegra_udelay(unsigned long usecs);
221
222 void __init tegra_init_timer(void)
223 {
224         struct clk *clk;
225         int ret;
226         unsigned long rate;
227
228         clk = clk_get_sys("timer", NULL);
229         if (IS_ERR(clk)) {
230                 pr_warn("Unable to get timer clock. Assuming 12Mhz input clock.\n");
231                 rate = 12000000;
232         } else {
233                 clk_prepare_enable(clk);
234                 rate = clk_get_rate(clk);
235         }
236
237         /*
238          * rtc registers are used by read_persistent_clock, keep the rtc clock
239          * enabled
240          */
241         clk = clk_get_sys("rtc-tegra", NULL);
242         if (IS_ERR(clk))
243                 pr_warn("Unable to get rtc-tegra clock\n");
244         else
245                 clk_prepare_enable(clk);
246
247 #ifdef CONFIG_ARCH_TEGRA_2x_SOC
248         tegra2_init_timer(&system_timer, &tegra_timer_irq.irq, rate);
249 #else
250         tegra3_init_timer(&system_timer, &tegra_timer_irq.irq, rate);
251 #endif
252
253         setup_sched_clock(tegra_read_sched_clock, 32, 1000000);
254
255         if (clocksource_mmio_init(timer_reg_base + TIMERUS_CNTR_1US,
256                 "timer_us", 1000000, 300, 32, clocksource_mmio_readl_up)) {
257                 pr_err("Failed to register clocksource\n");
258                 BUG();
259         }
260
261         ret = setup_irq(tegra_timer_irq.irq, &tegra_timer_irq);
262         if (ret) {
263                 pr_err("Failed to register timer IRQ: %d\n", ret);
264                 BUG();
265         }
266
267         clockevents_calc_mult_shift(&tegra_clockevent, 1000000, 5);
268         tegra_clockevent.max_delta_ns =
269                 clockevent_delta2ns(0x1fffffff, &tegra_clockevent);
270         tegra_clockevent.min_delta_ns =
271                 clockevent_delta2ns(0x1, &tegra_clockevent);
272         tegra_clockevent.cpumask = cpu_all_mask;
273         tegra_clockevent.irq = tegra_timer_irq.irq;
274         clockevents_register_device(&tegra_clockevent);
275
276         tegra_twd_init();
277         register_syscore_ops(&tegra_timer_syscore_ops);
278
279         register_persistent_clock(NULL, tegra_read_persistent_clock);
280
281         arm_delay_ops.delay             = __tegra_delay;
282         arm_delay_ops.const_udelay      = __tegra_const_udelay;
283         arm_delay_ops.udelay            = __tegra_udelay;
284 }