cd62da5f61d819727ce1b48d500445f6c00e09e8
[firefly-linux-kernel-4.4.55.git] / arch / arm / mach-rk29 / timer.c
1 /* linux/arch/arm/mach-rk29/timer.c
2  *
3  * Copyright (C) 2010 ROCKCHIP, Inc.
4  *
5  * This software is licensed under the terms of the GNU General Public
6  * License version 2, as published by the Free Software Foundation, and
7  * may be copied, distributed, and modified under those terms.
8  *
9  * This program is distributed in the hope that it will be useful,
10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12  * GNU General Public License for more details.
13  *
14  */
15
16 #include <linux/init.h>
17 #include <linux/time.h>
18 #include <linux/interrupt.h>
19 #include <linux/irq.h>
20 #include <linux/clk.h>
21 #include <linux/clockchips.h>
22 #include <linux/io.h>
23 #include <linux/cpufreq.h>
24
25 #include <asm/mach/time.h>
26 #include <mach/rk29_iomap.h>
27
28 #define TIMER_LOAD_COUNT        0x0000
29 #define TIMER_CUR_VALUE         0x0004
30 #define TIMER_CONTROL_REG       0x0008
31 #define TIMER_EOI               0x000C
32 #define TIMER_INT_STATUS        0x0010
33
34 #define TIMER_DISABLE                   4
35 #define TIMER_ENABLE                    3
36 #define TIMER_ENABLE_FREE_RUNNING       1
37
38 #define CHECK_VBUS_MS                   1000    /* ms */
39
40 #define RK_TIMER_ENABLE(n)              writel(TIMER_ENABLE, RK29_TIMER0_BASE + 0x14 * (n - 1) + TIMER_CONTROL_REG)
41 #define RK_TIMER_ENABLE_FREE_RUNNING(n) writel(TIMER_ENABLE_FREE_RUNNING, RK29_TIMER0_BASE + 0x14 * (n - 1) + TIMER_CONTROL_REG)
42 #define RK_TIMER_DISABLE(n)             writel(TIMER_DISABLE, RK29_TIMER0_BASE + 0x14 * (n - 1) + TIMER_CONTROL_REG)
43
44 #define RK_TIMER_SETCOUNT(n, count)     writel(count, RK29_TIMER0_BASE + 0x14 * (n - 1) + TIMER_LOAD_COUNT)
45 #define RK_TIMER_GETCOUNT(n)            readl(RK29_TIMER0_BASE + 0x14 * (n - 1) + TIMER_LOAD_COUNT)
46
47 #define RK_TIMER_READVALUE(n)           readl(RK29_TIMER0_BASE + 0x14 * (n - 1) + TIMER_CUR_VALUE)
48 #define RK_TIMER_INT_CLEAR(n)           readl(RK29_TIMER0_BASE + 0x14 * (n - 1) + TIMER_EOI)
49
50 #define TIMER_CLKEVT                    2       /* timer2 */
51 #define IRQ_NR_TIMER_CLKEVT             IRQ_NR_TIMER2
52 #define TIMER_CLKEVT_NAME               "timer2"
53
54 #define TIMER_CLKSRC                    3       /* timer3 */
55 #define IRQ_NR_TIMER_CLKSRC             IRQ_NR_TIMER3
56 #define TIMER_CLKSRC_NAME               "timer3"
57
58 static struct clk *timer_clk;
59 static volatile unsigned long timer_mult; /* timer count = cycle * timer_mult */
60
61 void rk29_timer_update_mult(void)
62 {
63         //if (timer_clk)
64         //      timer_mult = clk_get_rate(timer_clk) / 1000000;
65 }
66
67 static int rk29_timer_set_next_event(unsigned long cycles, struct clock_event_device *evt)
68 {
69         RK_TIMER_DISABLE(TIMER_CLKEVT);
70         RK_TIMER_SETCOUNT(TIMER_CLKEVT, cycles * timer_mult);
71         RK_TIMER_ENABLE(TIMER_CLKEVT);
72
73         return 0;
74 }
75
76 static void rk29_timer_set_mode(enum clock_event_mode mode, struct clock_event_device *evt)
77 {
78         switch (mode) {
79         case CLOCK_EVT_MODE_RESUME:
80         case CLOCK_EVT_MODE_PERIODIC:
81         case CLOCK_EVT_MODE_ONESHOT:
82                 break;
83         case CLOCK_EVT_MODE_UNUSED:
84         case CLOCK_EVT_MODE_SHUTDOWN:
85                 RK_TIMER_DISABLE(TIMER_CLKEVT);
86                 break;
87         }
88 }
89
90 static struct clock_event_device rk29_timer_clockevent = {
91         .name           = TIMER_CLKEVT_NAME,
92         .features       = CLOCK_EVT_FEAT_ONESHOT,
93         .shift          = 32,
94         .rating         = 200,
95         .set_next_event = rk29_timer_set_next_event,
96         .set_mode       = rk29_timer_set_mode,
97 };
98
99 static irqreturn_t rk29_timer_clockevent_interrupt(int irq, void *dev_id)
100 {
101         struct clock_event_device *evt = dev_id;
102
103         RK_TIMER_INT_CLEAR(TIMER_CLKEVT);
104         RK_TIMER_DISABLE(TIMER_CLKEVT);
105
106         evt->event_handler(evt);
107
108         return IRQ_HANDLED;
109 }
110
111 static struct irqaction rk29_timer_clockevent_irq = {
112         .name           = TIMER_CLKEVT_NAME,
113         .flags          = IRQF_DISABLED | IRQF_TIMER,
114         .handler        = rk29_timer_clockevent_interrupt,
115         .irq            = IRQ_NR_TIMER_CLKEVT,
116         .dev_id         = &rk29_timer_clockevent,
117 };
118
119 static int rk29_timer_cpufreq_notifier(struct notifier_block *nb, unsigned long val, void *data)
120 {
121         if (val == CPUFREQ_POSTCHANGE) {
122                 rk29_timer_update_mult();
123         }
124
125         return 0;
126 }
127
128 static struct notifier_block rk29_timer_cpufreq_notifier_block = {
129         .notifier_call  = rk29_timer_cpufreq_notifier,
130         .priority       = 0x7ffffff,
131 };
132
133 static __init int rk29_timer_init_cpufreq(void)
134 {
135         cpufreq_register_notifier(&rk29_timer_cpufreq_notifier_block, CPUFREQ_TRANSITION_NOTIFIER);
136         return 0;
137 }
138
139 arch_initcall_sync(rk29_timer_init_cpufreq);
140
141 static __init int rk29_timer_init_clockevent(void)
142 {
143         struct clock_event_device *ce = &rk29_timer_clockevent;
144
145         //timer_clk = clk_get(NULL, "timer");
146         rk29_timer_update_mult();
147
148         RK_TIMER_DISABLE(TIMER_CLKEVT);
149
150         setup_irq(rk29_timer_clockevent_irq.irq, &rk29_timer_clockevent_irq);
151
152         ce->mult = div_sc(1000000, NSEC_PER_SEC, ce->shift);
153         ce->max_delta_ns = clockevent_delta2ns(0xFFFFFFFFUL / 256, ce); // max pclk < 256MHz
154         ce->min_delta_ns = clockevent_delta2ns(1, ce) + 1;
155
156         ce->cpumask = cpumask_of(0);
157
158         clockevents_register_device(ce);
159
160         return 0;
161 }
162
163 static cycle_t rk29_timer_read(struct clocksource *cs)
164 {
165         return ~RK_TIMER_READVALUE(TIMER_CLKSRC);
166 }
167
168 static struct clocksource rk29_timer_clocksource = {
169         .name           = TIMER_CLKSRC_NAME,
170         .rating         = 200,
171         .read           = rk29_timer_read,
172         .mask           = CLOCKSOURCE_MASK(32),
173         .shift          = 26,
174         .flags          = CLOCK_SOURCE_IS_CONTINUOUS,
175 };
176
177 static void __init rk29_timer_init_clocksource(void)
178 {
179         static char err[] __initdata = KERN_ERR "%s: can't register clocksource!\n";
180         struct clocksource *cs = &rk29_timer_clocksource;
181
182         RK_TIMER_DISABLE(TIMER_CLKSRC);
183         RK_TIMER_SETCOUNT(TIMER_CLKSRC, 0xFFFFFFFF);
184         RK_TIMER_ENABLE_FREE_RUNNING(TIMER_CLKSRC);
185
186         cs->mult = clocksource_hz2mult(24000000, cs->shift);
187         if (clocksource_register(cs))
188                 printk(err, cs->name);
189
190 }
191
192 static void __init rk29_timer_init(void)
193 {
194         rk29_timer_init_clocksource();
195         rk29_timer_init_clockevent();
196 }
197
198 struct sys_timer rk29_timer = {
199         .init = rk29_timer_init
200 };
201
202
203
204
205
206