projects/linux·blob uaccess-cleanups · refs

304 lines · 7.1 KiB

1// SPDX-License-Identifier: GPL-2.0
2// Copyright (C) 2012 MIPS Technologies, Inc. All rights reserved.
3
4#define pr_fmt(fmt) "mips-gic-timer: " fmt
5
6#include <linux/clk.h>
7#include <linux/clockchips.h>
8#include <linux/cpu.h>
9#include <linux/init.h>
10#include <linux/interrupt.h>
11#include <linux/notifier.h>
12#include <linux/of_irq.h>
13#include <linux/percpu.h>
14#include <linux/sched_clock.h>
15#include <linux/smp.h>
16#include <linux/time.h>
17#include <asm/mips-cps.h>
18
19static DEFINE_PER_CPU(struct clock_event_device, gic_clockevent_device);
20static int gic_timer_irq;
21static unsigned int gic_frequency;
22static unsigned int gic_count_width;
23static bool __read_mostly gic_clock_unstable;
24
25static void gic_clocksource_unstable(char *reason);
26
27static u64 notrace gic_read_count_2x32(void)
28{
29 unsigned int hi, hi2, lo;
30
31 do {
32 hi = read_gic_counter_32h();
33 lo = read_gic_counter_32l();
34 hi2 = read_gic_counter_32h();
35 } while (hi2 != hi);
36
37 return (((u64) hi) << 32) + lo;
38}
39
40static u64 notrace gic_read_count_64(void)
41{
42 return read_gic_counter();
43}
44
45static u64 notrace gic_read_count(void)
46{
47 if (mips_cm_is64)
48 return gic_read_count_64();
49
50 return gic_read_count_2x32();
51}
52
53static int gic_next_event(unsigned long delta, struct clock_event_device *evt)
54{
55 int cpu = cpumask_first(evt->cpumask);
56 u64 cnt;
57 int res;
58
59 cnt = gic_read_count();
60 cnt += (u64)delta;
61 if (cpu == raw_smp_processor_id()) {
62 write_gic_vl_compare(cnt);
63 } else {
64 write_gic_vl_other(mips_cm_vp_id(cpu));
65 write_gic_vo_compare(cnt);
66 }
67 res = ((int)(gic_read_count() - cnt) >= 0) ? -ETIME : 0;
68 return res;
69}
70
71static irqreturn_t gic_compare_interrupt(int irq, void *dev_id)
72{
73 struct clock_event_device *cd = dev_id;
74
75 write_gic_vl_compare(read_gic_vl_compare());
76 cd->event_handler(cd);
77 return IRQ_HANDLED;
78}
79
80static void gic_clockevent_cpu_init(unsigned int cpu,
81 struct clock_event_device *cd)
82{
83 cd->name = "MIPS GIC";
84 cd->features = CLOCK_EVT_FEAT_ONESHOT |
85 CLOCK_EVT_FEAT_C3STOP;
86
87 cd->rating = 350;
88 cd->irq = gic_timer_irq;
89 cd->cpumask = cpumask_of(cpu);
90 cd->set_next_event = gic_next_event;
91
92 clockevents_config_and_register(cd, gic_frequency, 0x300, 0x7fffffff);
93
94 enable_percpu_irq(gic_timer_irq, IRQ_TYPE_NONE);
95}
96
97static void gic_clockevent_cpu_exit(struct clock_event_device *cd)
98{
99 disable_percpu_irq(gic_timer_irq);
100}
101
102static void gic_update_frequency(void *data)
103{
104 unsigned long rate = (unsigned long)data;
105
106 clockevents_update_freq(this_cpu_ptr(&gic_clockevent_device), rate);
107}
108
109static int gic_starting_cpu(unsigned int cpu)
110{
111 /* Ensure the GIC counter is running */
112 clear_gic_config(GIC_CONFIG_COUNTSTOP);
113
114 gic_clockevent_cpu_init(cpu, this_cpu_ptr(&gic_clockevent_device));
115 return 0;
116}
117
118static int gic_clk_notifier(struct notifier_block *nb, unsigned long action,
119 void *data)
120{
121 struct clk_notifier_data *cnd = data;
122
123 if (action == POST_RATE_CHANGE) {
124 gic_clocksource_unstable("ref clock rate change");
125 on_each_cpu(gic_update_frequency, (void *)cnd->new_rate, 1);
126 }
127
128 return NOTIFY_OK;
129}
130
131static int gic_dying_cpu(unsigned int cpu)
132{
133 gic_clockevent_cpu_exit(this_cpu_ptr(&gic_clockevent_device));
134 return 0;
135}
136
137static struct notifier_block gic_clk_nb = {
138 .notifier_call = gic_clk_notifier,
139};
140
141static int gic_clockevent_init(void)
142{
143 int ret;
144
145 if (!gic_frequency)
146 return -ENXIO;
147
148 ret = request_percpu_irq(gic_timer_irq, gic_compare_interrupt,
149 "timer", &gic_clockevent_device);
150 if (ret < 0) {
151 pr_err("IRQ %d setup failed (%d)\n", gic_timer_irq, ret);
152 return ret;
153 }
154
155 cpuhp_setup_state(CPUHP_AP_MIPS_GIC_TIMER_STARTING,
156 "clockevents/mips/gic/timer:starting",
157 gic_starting_cpu, gic_dying_cpu);
158 return 0;
159}
160
161static u64 gic_hpt_read(struct clocksource *cs)
162{
163 return gic_read_count();
164}
165
166static u64 gic_hpt_read_multicluster(struct clocksource *cs)
167{
168 unsigned int hi, hi2, lo;
169 u64 count;
170
171 mips_cm_lock_other(0, 0, 0, CM_GCR_Cx_OTHER_BLOCK_GLOBAL);
172
173 if (mips_cm_is64) {
174 count = read_gic_redir_counter();
175 goto out;
176 }
177
178 hi = read_gic_redir_counter_32h();
179 while (true) {
180 lo = read_gic_redir_counter_32l();
181
182 /* If hi didn't change then lo didn't wrap & we're done */
183 hi2 = read_gic_redir_counter_32h();
184 if (hi2 == hi)
185 break;
186
187 /* Otherwise, repeat with the latest hi value */
188 hi = hi2;
189 }
190
191 count = (((u64)hi) << 32) + lo;
192out:
193 mips_cm_unlock_other();
194 return count;
195}
196
197static struct clocksource gic_clocksource = {
198 .name = "GIC",
199 .read = gic_hpt_read,
200 .flags = CLOCK_SOURCE_IS_CONTINUOUS,
201 .vdso_clock_mode = VDSO_CLOCKMODE_GIC,
202};
203
204static void gic_clocksource_unstable(char *reason)
205{
206 if (gic_clock_unstable)
207 return;
208
209 gic_clock_unstable = true;
210
211 pr_info("GIC timer is unstable due to %s\n", reason);
212
213 clocksource_mark_unstable(&gic_clocksource);
214}
215
216static int __init __gic_clocksource_init(void)
217{
218 int ret;
219
220 /* Set clocksource mask. */
221 gic_count_width = read_gic_config() & GIC_CONFIG_COUNTBITS;
222 gic_count_width >>= __ffs(GIC_CONFIG_COUNTBITS);
223 gic_count_width *= 4;
224 gic_count_width += 32;
225 gic_clocksource.mask = CLOCKSOURCE_MASK(gic_count_width);
226
227 /* Calculate a somewhat reasonable rating value. */
228 if (mips_cm_revision() >= CM_REV_CM3 || !IS_ENABLED(CONFIG_CPU_FREQ))
229 gic_clocksource.rating = 300; /* Good when frequecy is stable */
230 else
231 gic_clocksource.rating = 200;
232 gic_clocksource.rating += clamp(gic_frequency / 10000000, 0, 99);
233
234 if (mips_cps_multicluster_cpus()) {
235 gic_clocksource.read = &gic_hpt_read_multicluster;
236 gic_clocksource.vdso_clock_mode = VDSO_CLOCKMODE_NONE;
237 }
238
239 ret = clocksource_register_hz(&gic_clocksource, gic_frequency);
240 if (ret < 0)
241 pr_warn("Unable to register clocksource\n");
242
243 return ret;
244}
245
246static int __init gic_clocksource_of_init(struct device_node *node)
247{
248 struct clk *clk;
249 int ret;
250
251 if (!mips_gic_present() || !node->parent ||
252 !of_device_is_compatible(node->parent, "mti,gic")) {
253 pr_warn("No DT definition\n");
254 return -ENXIO;
255 }
256
257 clk = of_clk_get(node, 0);
258 if (!IS_ERR(clk)) {
259 ret = clk_prepare_enable(clk);
260 if (ret < 0) {
261 pr_err("Failed to enable clock\n");
262 clk_put(clk);
263 return ret;
264 }
265
266 gic_frequency = clk_get_rate(clk);
267 } else if (of_property_read_u32(node, "clock-frequency",
268 &gic_frequency)) {
269 pr_err("Frequency not specified\n");
270 return -EINVAL;
271 }
272 gic_timer_irq = irq_of_parse_and_map(node, 0);
273 if (!gic_timer_irq) {
274 pr_err("IRQ not specified\n");
275 return -EINVAL;
276 }
277
278 ret = __gic_clocksource_init();
279 if (ret)
280 return ret;
281
282 ret = gic_clockevent_init();
283 if (!ret && !IS_ERR(clk)) {
284 if (clk_notifier_register(clk, &gic_clk_nb) < 0)
285 pr_warn("Unable to register clock notifier\n");
286 }
287
288 /*
289 * It's safe to use the MIPS GIC timer as a sched clock source only if
290 * its ticks are stable, which is true on either the platforms with
291 * stable CPU frequency or on the platforms with CM3 and CPU frequency
292 * change performed by the CPC core clocks divider.
293 */
294 if ((mips_cm_revision() >= CM_REV_CM3 || !IS_ENABLED(CONFIG_CPU_FREQ)) &&
295 !mips_cps_multicluster_cpus()) {
296 sched_clock_register(mips_cm_is64 ?
297 gic_read_count_64 : gic_read_count_2x32,
298 gic_count_width, gic_frequency);
299 }
300
301 return 0;
302}
303TIMER_OF_DECLARE(mips_gic_timer, "mti,gic-timer",
304 gic_clocksource_of_init);