Root/
Source at commit 694c7fbe86b8a9c91392e505afcb9fcfc91deccc created 12 years 6 months ago. By Maarten ter Huurne, MIPS: JZ4740: Add cpufreq support | |
---|---|
1 | /* |
2 | * Copyright (C) 2010, Lars-Peter Clausen <lars@metafoo.de> |
3 | * JZ4740 platform time support |
4 | * |
5 | * This program is free software; you can redistribute it and/or modify it |
6 | * under the terms of the GNU General Public License as published by the |
7 | * Free Software Foundation; either version 2 of the License, or (at your |
8 | * option) any later version. |
9 | * |
10 | * You should have received a copy of the GNU General Public License along |
11 | * with this program; if not, write to the Free Software Foundation, Inc., |
12 | * 675 Mass Ave, Cambridge, MA 02139, USA. |
13 | * |
14 | */ |
15 | |
16 | #include <linux/interrupt.h> |
17 | #include <linux/kernel.h> |
18 | #include <linux/time.h> |
19 | |
20 | #include <linux/clockchips.h> |
21 | |
22 | #include <asm/mach-jz4740/irq.h> |
23 | #include <asm/mach-jz4740/timer.h> |
24 | #include <asm/time.h> |
25 | |
26 | #include "clock.h" |
27 | |
28 | #define TIMER_CLOCKEVENT 0 |
29 | #define TIMER_CLOCKSOURCE 1 |
30 | |
31 | static uint16_t jz4740_jiffies_per_tick; |
32 | |
33 | static cycle_t jz4740_clocksource_read(struct clocksource *cs) |
34 | { |
35 | return jz4740_timer_get_count(TIMER_CLOCKSOURCE); |
36 | } |
37 | |
38 | static struct clocksource jz4740_clocksource = { |
39 | .name = "jz4740-timer", |
40 | .rating = 200, |
41 | .read = jz4740_clocksource_read, |
42 | .mask = CLOCKSOURCE_MASK(16), |
43 | .flags = CLOCK_SOURCE_IS_CONTINUOUS, |
44 | }; |
45 | |
46 | static irqreturn_t jz4740_clockevent_irq(int irq, void *devid) |
47 | { |
48 | struct clock_event_device *cd = devid; |
49 | |
50 | jz4740_timer_ack_full(TIMER_CLOCKEVENT); |
51 | |
52 | if (cd->mode != CLOCK_EVT_MODE_PERIODIC) |
53 | jz4740_timer_disable(TIMER_CLOCKEVENT); |
54 | |
55 | cd->event_handler(cd); |
56 | |
57 | return IRQ_HANDLED; |
58 | } |
59 | |
60 | static void jz4740_clockevent_set_mode(enum clock_event_mode mode, |
61 | struct clock_event_device *cd) |
62 | { |
63 | switch (mode) { |
64 | case CLOCK_EVT_MODE_PERIODIC: |
65 | jz4740_timer_set_count(TIMER_CLOCKEVENT, 0); |
66 | jz4740_timer_set_period(TIMER_CLOCKEVENT, jz4740_jiffies_per_tick); |
67 | case CLOCK_EVT_MODE_RESUME: |
68 | jz4740_timer_irq_full_enable(TIMER_CLOCKEVENT); |
69 | jz4740_timer_enable(TIMER_CLOCKEVENT); |
70 | break; |
71 | case CLOCK_EVT_MODE_ONESHOT: |
72 | case CLOCK_EVT_MODE_SHUTDOWN: |
73 | jz4740_timer_disable(TIMER_CLOCKEVENT); |
74 | break; |
75 | default: |
76 | break; |
77 | } |
78 | } |
79 | |
80 | static int jz4740_clockevent_set_next(unsigned long evt, |
81 | struct clock_event_device *cd) |
82 | { |
83 | jz4740_timer_set_count(TIMER_CLOCKEVENT, 0); |
84 | jz4740_timer_set_period(TIMER_CLOCKEVENT, evt); |
85 | jz4740_timer_enable(TIMER_CLOCKEVENT); |
86 | |
87 | return 0; |
88 | } |
89 | |
90 | static struct clock_event_device jz4740_clockevent = { |
91 | .name = "jz4740-timer", |
92 | .features = CLOCK_EVT_FEAT_PERIODIC | CLOCK_EVT_FEAT_ONESHOT, |
93 | .set_next_event = jz4740_clockevent_set_next, |
94 | .set_mode = jz4740_clockevent_set_mode, |
95 | .rating = 200, |
96 | .irq = JZ4740_IRQ_TCU0, |
97 | }; |
98 | |
99 | static struct irqaction timer_irqaction = { |
100 | .handler = jz4740_clockevent_irq, |
101 | .flags = IRQF_PERCPU | IRQF_TIMER, |
102 | .name = "jz4740-timerirq", |
103 | .dev_id = &jz4740_clockevent, |
104 | }; |
105 | |
106 | void __init plat_time_init(void) |
107 | { |
108 | int ret; |
109 | uint32_t clk_rate; |
110 | uint16_t ctrl; |
111 | |
112 | jz4740_timer_init(); |
113 | |
114 | clk_rate = jz4740_clock_bdata.ext_rate >> 4; |
115 | jz4740_jiffies_per_tick = DIV_ROUND_CLOSEST(clk_rate, HZ); |
116 | |
117 | clockevent_set_clock(&jz4740_clockevent, clk_rate); |
118 | jz4740_clockevent.min_delta_ns = clockevent_delta2ns(100, &jz4740_clockevent); |
119 | jz4740_clockevent.max_delta_ns = clockevent_delta2ns(0xffff, &jz4740_clockevent); |
120 | jz4740_clockevent.cpumask = cpumask_of(0); |
121 | |
122 | clockevents_register_device(&jz4740_clockevent); |
123 | |
124 | ret = clocksource_register_hz(&jz4740_clocksource, clk_rate); |
125 | |
126 | if (ret) |
127 | printk(KERN_ERR "Failed to register clocksource: %d\n", ret); |
128 | |
129 | setup_irq(JZ4740_IRQ_TCU0, &timer_irqaction); |
130 | |
131 | ctrl = JZ_TIMER_CTRL_PRESCALE_16 | JZ_TIMER_CTRL_SRC_EXT; |
132 | |
133 | jz4740_timer_set_ctrl(TIMER_CLOCKEVENT, ctrl); |
134 | jz4740_timer_set_ctrl(TIMER_CLOCKSOURCE, ctrl); |
135 | |
136 | jz4740_timer_set_period(TIMER_CLOCKEVENT, jz4740_jiffies_per_tick); |
137 | jz4740_timer_irq_full_enable(TIMER_CLOCKEVENT); |
138 | |
139 | jz4740_timer_set_period(TIMER_CLOCKSOURCE, 0xffff); |
140 | |
141 | jz4740_timer_enable(TIMER_CLOCKEVENT); |
142 | jz4740_timer_enable(TIMER_CLOCKSOURCE); |
143 | } |
144 |
Branches:
ben-wpan
ben-wpan-stefan
javiroman/ks7010
jz-2.6.34
jz-2.6.34-rc5
jz-2.6.34-rc6
jz-2.6.34-rc7
jz-2.6.35
jz-2.6.36
jz-2.6.37
jz-2.6.38
jz-2.6.39
jz-3.0
jz-3.1
jz-3.11
jz-3.12
jz-3.13
jz-3.15
jz-3.16
jz-3.18-dt
jz-3.2
jz-3.3
jz-3.4
jz-3.5
jz-3.6
jz-3.6-rc2-pwm
jz-3.9
jz-3.9-clk
jz-3.9-rc8
jz47xx
jz47xx-2.6.38
master
Tags:
od-2011-09-04
od-2011-09-18
v2.6.34-rc5
v2.6.34-rc6
v2.6.34-rc7
v3.9