xref: /openbmc/qemu/hw/timer/aspeed_timer.c (revision 5cc8767d)
1 /*
2  * ASPEED AST2400 Timer
3  *
4  * Andrew Jeffery <andrew@aj.id.au>
5  *
6  * Copyright (C) 2016 IBM Corp.
7  *
8  * This code is licensed under the GPL version 2 or later.  See
9  * the COPYING file in the top-level directory.
10  */
11 
12 #include "qemu/osdep.h"
13 #include "qapi/error.h"
14 #include "hw/sysbus.h"
15 #include "hw/timer/aspeed_timer.h"
16 #include "qemu/bitops.h"
17 #include "qemu/timer.h"
18 #include "qemu/log.h"
19 #include "qemu/module.h"
20 #include "trace.h"
21 
22 #define TIMER_NR_REGS 4
23 
24 #define TIMER_CTRL_BITS 4
25 #define TIMER_CTRL_MASK ((1 << TIMER_CTRL_BITS) - 1)
26 
27 #define TIMER_CLOCK_USE_EXT true
28 #define TIMER_CLOCK_EXT_HZ 1000000
29 #define TIMER_CLOCK_USE_APB false
30 
31 #define TIMER_REG_STATUS 0
32 #define TIMER_REG_RELOAD 1
33 #define TIMER_REG_MATCH_FIRST 2
34 #define TIMER_REG_MATCH_SECOND 3
35 
36 #define TIMER_FIRST_CAP_PULSE 4
37 
38 enum timer_ctrl_op {
39     op_enable = 0,
40     op_external_clock,
41     op_overflow_interrupt,
42     op_pulse_enable
43 };
44 
45 /**
46  * Avoid mutual references between AspeedTimerCtrlState and AspeedTimer
47  * structs, as it's a waste of memory. The ptimer BH callback needs to know
48  * whether a specific AspeedTimer is enabled, but this information is held in
49  * AspeedTimerCtrlState. So, provide a helper to hoist ourselves from an
50  * arbitrary AspeedTimer to AspeedTimerCtrlState.
51  */
52 static inline AspeedTimerCtrlState *timer_to_ctrl(AspeedTimer *t)
53 {
54     const AspeedTimer (*timers)[] = (void *)t - (t->id * sizeof(*t));
55     return container_of(timers, AspeedTimerCtrlState, timers);
56 }
57 
58 static inline bool timer_ctrl_status(AspeedTimer *t, enum timer_ctrl_op op)
59 {
60     return !!(timer_to_ctrl(t)->ctrl & BIT(t->id * TIMER_CTRL_BITS + op));
61 }
62 
63 static inline bool timer_enabled(AspeedTimer *t)
64 {
65     return timer_ctrl_status(t, op_enable);
66 }
67 
68 static inline bool timer_overflow_interrupt(AspeedTimer *t)
69 {
70     return timer_ctrl_status(t, op_overflow_interrupt);
71 }
72 
73 static inline bool timer_can_pulse(AspeedTimer *t)
74 {
75     return t->id >= TIMER_FIRST_CAP_PULSE;
76 }
77 
78 static inline bool timer_external_clock(AspeedTimer *t)
79 {
80     return timer_ctrl_status(t, op_external_clock);
81 }
82 
83 static inline uint32_t calculate_rate(struct AspeedTimer *t)
84 {
85     AspeedTimerCtrlState *s = timer_to_ctrl(t);
86 
87     return timer_external_clock(t) ? TIMER_CLOCK_EXT_HZ : s->scu->apb_freq;
88 }
89 
90 static inline uint32_t calculate_ticks(struct AspeedTimer *t, uint64_t now_ns)
91 {
92     uint64_t delta_ns = now_ns - MIN(now_ns, t->start);
93     uint32_t rate = calculate_rate(t);
94     uint64_t ticks = muldiv64(delta_ns, rate, NANOSECONDS_PER_SECOND);
95 
96     return t->reload - MIN(t->reload, ticks);
97 }
98 
99 static inline uint64_t calculate_time(struct AspeedTimer *t, uint32_t ticks)
100 {
101     uint64_t delta_ns;
102     uint64_t delta_ticks;
103 
104     delta_ticks = t->reload - MIN(t->reload, ticks);
105     delta_ns = muldiv64(delta_ticks, NANOSECONDS_PER_SECOND, calculate_rate(t));
106 
107     return t->start + delta_ns;
108 }
109 
110 static inline uint32_t calculate_match(struct AspeedTimer *t, int i)
111 {
112     return t->match[i] < t->reload ? t->match[i] : 0;
113 }
114 
115 static uint64_t calculate_next(struct AspeedTimer *t)
116 {
117     uint64_t now = qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL);
118     uint64_t next;
119 
120     /*
121      * We don't know the relationship between the values in the match
122      * registers, so sort using MAX/MIN/zero. We sort in that order as
123      * the timer counts down to zero.
124      */
125 
126     next = calculate_time(t, MAX(calculate_match(t, 0), calculate_match(t, 1)));
127     if (now < next) {
128         return next;
129     }
130 
131     next = calculate_time(t, MIN(calculate_match(t, 0), calculate_match(t, 1)));
132     if (now < next) {
133         return next;
134     }
135 
136     next = calculate_time(t, 0);
137     if (now < next) {
138         return next;
139     }
140 
141     /* We've missed all deadlines, fire interrupt and try again */
142     timer_del(&t->timer);
143 
144     if (timer_overflow_interrupt(t)) {
145         t->level = !t->level;
146         qemu_set_irq(t->irq, t->level);
147     }
148 
149     next = MAX(MAX(calculate_match(t, 0), calculate_match(t, 1)), 0);
150     t->start = qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL);
151 
152     return calculate_time(t, next);
153 }
154 
155 static void aspeed_timer_mod(AspeedTimer *t)
156 {
157     uint64_t next = calculate_next(t);
158     if (next) {
159         timer_mod(&t->timer, next);
160     }
161 }
162 
163 static void aspeed_timer_expire(void *opaque)
164 {
165     AspeedTimer *t = opaque;
166     bool interrupt = false;
167     uint32_t ticks;
168 
169     if (!timer_enabled(t)) {
170         return;
171     }
172 
173     ticks = calculate_ticks(t, qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL));
174 
175     if (!ticks) {
176         interrupt = timer_overflow_interrupt(t) || !t->match[0] || !t->match[1];
177     } else if (ticks <= MIN(t->match[0], t->match[1])) {
178         interrupt = true;
179     } else if (ticks <= MAX(t->match[0], t->match[1])) {
180         interrupt = true;
181     }
182 
183     if (interrupt) {
184         t->level = !t->level;
185         qemu_set_irq(t->irq, t->level);
186     }
187 
188     aspeed_timer_mod(t);
189 }
190 
191 static uint64_t aspeed_timer_get_value(AspeedTimer *t, int reg)
192 {
193     uint64_t value;
194 
195     switch (reg) {
196     case TIMER_REG_STATUS:
197         if (timer_enabled(t)) {
198             value = calculate_ticks(t, qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL));
199         } else {
200             value = t->reload;
201         }
202         break;
203     case TIMER_REG_RELOAD:
204         value = t->reload;
205         break;
206     case TIMER_REG_MATCH_FIRST:
207     case TIMER_REG_MATCH_SECOND:
208         value = t->match[reg - 2];
209         break;
210     default:
211         qemu_log_mask(LOG_UNIMP, "%s: Programming error: unexpected reg: %d\n",
212                       __func__, reg);
213         value = 0;
214         break;
215     }
216     return value;
217 }
218 
219 static uint64_t aspeed_timer_read(void *opaque, hwaddr offset, unsigned size)
220 {
221     AspeedTimerCtrlState *s = opaque;
222     const int reg = (offset & 0xf) / 4;
223     uint64_t value;
224 
225     switch (offset) {
226     case 0x30: /* Control Register */
227         value = s->ctrl;
228         break;
229     case 0x34: /* Control Register 2 */
230         value = s->ctrl2;
231         break;
232     case 0x00 ... 0x2c: /* Timers 1 - 4 */
233         value = aspeed_timer_get_value(&s->timers[(offset >> 4)], reg);
234         break;
235     case 0x40 ... 0x8c: /* Timers 5 - 8 */
236         value = aspeed_timer_get_value(&s->timers[(offset >> 4) - 1], reg);
237         break;
238     /* Illegal */
239     case 0x38:
240     case 0x3C:
241     default:
242         qemu_log_mask(LOG_GUEST_ERROR, "%s: Bad offset 0x%" HWADDR_PRIx "\n",
243                 __func__, offset);
244         value = 0;
245         break;
246     }
247     trace_aspeed_timer_read(offset, size, value);
248     return value;
249 }
250 
251 static void aspeed_timer_set_value(AspeedTimerCtrlState *s, int timer, int reg,
252                                    uint32_t value)
253 {
254     AspeedTimer *t;
255     uint32_t old_reload;
256 
257     trace_aspeed_timer_set_value(timer, reg, value);
258     t = &s->timers[timer];
259     switch (reg) {
260     case TIMER_REG_RELOAD:
261         old_reload = t->reload;
262         t->reload = value;
263 
264         /* If the reload value was not previously set, or zero, and
265          * the current value is valid, try to start the timer if it is
266          * enabled.
267          */
268         if (old_reload || !t->reload) {
269             break;
270         }
271 
272     case TIMER_REG_STATUS:
273         if (timer_enabled(t)) {
274             uint64_t now = qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL);
275             int64_t delta = (int64_t) value - (int64_t) calculate_ticks(t, now);
276             uint32_t rate = calculate_rate(t);
277 
278             if (delta >= 0) {
279                 t->start += muldiv64(delta, NANOSECONDS_PER_SECOND, rate);
280             } else {
281                 t->start -= muldiv64(-delta, NANOSECONDS_PER_SECOND, rate);
282             }
283             aspeed_timer_mod(t);
284         }
285         break;
286     case TIMER_REG_MATCH_FIRST:
287     case TIMER_REG_MATCH_SECOND:
288         t->match[reg - 2] = value;
289         if (timer_enabled(t)) {
290             aspeed_timer_mod(t);
291         }
292         break;
293     default:
294         qemu_log_mask(LOG_UNIMP, "%s: Programming error: unexpected reg: %d\n",
295                       __func__, reg);
296         break;
297     }
298 }
299 
300 /* Control register operations are broken out into helpers that can be
301  * explicitly called on aspeed_timer_reset(), but also from
302  * aspeed_timer_ctrl_op().
303  */
304 
305 static void aspeed_timer_ctrl_enable(AspeedTimer *t, bool enable)
306 {
307     trace_aspeed_timer_ctrl_enable(t->id, enable);
308     if (enable) {
309         t->start = qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL);
310         aspeed_timer_mod(t);
311     } else {
312         timer_del(&t->timer);
313     }
314 }
315 
316 static void aspeed_timer_ctrl_external_clock(AspeedTimer *t, bool enable)
317 {
318     trace_aspeed_timer_ctrl_external_clock(t->id, enable);
319 }
320 
321 static void aspeed_timer_ctrl_overflow_interrupt(AspeedTimer *t, bool enable)
322 {
323     trace_aspeed_timer_ctrl_overflow_interrupt(t->id, enable);
324 }
325 
326 static void aspeed_timer_ctrl_pulse_enable(AspeedTimer *t, bool enable)
327 {
328     if (timer_can_pulse(t)) {
329         trace_aspeed_timer_ctrl_pulse_enable(t->id, enable);
330     } else {
331         qemu_log_mask(LOG_GUEST_ERROR,
332                 "%s: Timer does not support pulse mode\n", __func__);
333     }
334 }
335 
336 /**
337  * Given the actions are fixed in number and completely described in helper
338  * functions, dispatch with a lookup table rather than manage control flow with
339  * a switch statement.
340  */
341 static void (*const ctrl_ops[])(AspeedTimer *, bool) = {
342     [op_enable] = aspeed_timer_ctrl_enable,
343     [op_external_clock] = aspeed_timer_ctrl_external_clock,
344     [op_overflow_interrupt] = aspeed_timer_ctrl_overflow_interrupt,
345     [op_pulse_enable] = aspeed_timer_ctrl_pulse_enable,
346 };
347 
348 /**
349  * Conditionally affect changes chosen by a timer's control bit.
350  *
351  * The aspeed_timer_ctrl_op() interface is convenient for the
352  * aspeed_timer_set_ctrl() function as the "no change" early exit can be
353  * calculated for all operations, which cleans up the caller code. However the
354  * interface isn't convenient for the reset function where we want to enter a
355  * specific state without artificially constructing old and new values that
356  * will fall through the change guard (and motivates extracting the actions
357  * out to helper functions).
358  *
359  * @t: The timer to manipulate
360  * @op: The type of operation to be performed
361  * @old: The old state of the timer's control bits
362  * @new: The incoming state for the timer's control bits
363  */
364 static void aspeed_timer_ctrl_op(AspeedTimer *t, enum timer_ctrl_op op,
365                                  uint8_t old, uint8_t new)
366 {
367     const uint8_t mask = BIT(op);
368     const bool enable = !!(new & mask);
369     const bool changed = ((old ^ new) & mask);
370     if (!changed) {
371         return;
372     }
373     ctrl_ops[op](t, enable);
374 }
375 
376 static void aspeed_timer_set_ctrl(AspeedTimerCtrlState *s, uint32_t reg)
377 {
378     int i;
379     int shift;
380     uint8_t t_old, t_new;
381     AspeedTimer *t;
382     const uint8_t enable_mask = BIT(op_enable);
383 
384     /* Handle a dependency between the 'enable' and remaining three
385      * configuration bits - i.e. if more than one bit in the control set has
386      * changed, including the 'enable' bit, then we want either disable the
387      * timer and perform configuration, or perform configuration and then
388      * enable the timer
389      */
390     for (i = 0; i < ASPEED_TIMER_NR_TIMERS; i++) {
391         t = &s->timers[i];
392         shift = (i * TIMER_CTRL_BITS);
393         t_old = (s->ctrl >> shift) & TIMER_CTRL_MASK;
394         t_new = (reg >> shift) & TIMER_CTRL_MASK;
395 
396         /* If we are disabling, do so first */
397         if ((t_old & enable_mask) && !(t_new & enable_mask)) {
398             aspeed_timer_ctrl_enable(t, false);
399         }
400         aspeed_timer_ctrl_op(t, op_external_clock, t_old, t_new);
401         aspeed_timer_ctrl_op(t, op_overflow_interrupt, t_old, t_new);
402         aspeed_timer_ctrl_op(t, op_pulse_enable, t_old, t_new);
403         /* If we are enabling, do so last */
404         if (!(t_old & enable_mask) && (t_new & enable_mask)) {
405             aspeed_timer_ctrl_enable(t, true);
406         }
407     }
408     s->ctrl = reg;
409 }
410 
411 static void aspeed_timer_set_ctrl2(AspeedTimerCtrlState *s, uint32_t value)
412 {
413     trace_aspeed_timer_set_ctrl2(value);
414 }
415 
416 static void aspeed_timer_write(void *opaque, hwaddr offset, uint64_t value,
417                                unsigned size)
418 {
419     const uint32_t tv = (uint32_t)(value & 0xFFFFFFFF);
420     const int reg = (offset & 0xf) / 4;
421     AspeedTimerCtrlState *s = opaque;
422 
423     switch (offset) {
424     /* Control Registers */
425     case 0x30:
426         aspeed_timer_set_ctrl(s, tv);
427         break;
428     case 0x34:
429         aspeed_timer_set_ctrl2(s, tv);
430         break;
431     /* Timer Registers */
432     case 0x00 ... 0x2c:
433         aspeed_timer_set_value(s, (offset >> TIMER_NR_REGS), reg, tv);
434         break;
435     case 0x40 ... 0x8c:
436         aspeed_timer_set_value(s, (offset >> TIMER_NR_REGS) - 1, reg, tv);
437         break;
438     /* Illegal */
439     case 0x38:
440     case 0x3C:
441     default:
442         qemu_log_mask(LOG_GUEST_ERROR, "%s: Bad offset 0x%" HWADDR_PRIx "\n",
443                 __func__, offset);
444         break;
445     }
446 }
447 
448 static const MemoryRegionOps aspeed_timer_ops = {
449     .read = aspeed_timer_read,
450     .write = aspeed_timer_write,
451     .endianness = DEVICE_LITTLE_ENDIAN,
452     .valid.min_access_size = 4,
453     .valid.max_access_size = 4,
454     .valid.unaligned = false,
455 };
456 
457 static void aspeed_init_one_timer(AspeedTimerCtrlState *s, uint8_t id)
458 {
459     AspeedTimer *t = &s->timers[id];
460 
461     t->id = id;
462     timer_init_ns(&t->timer, QEMU_CLOCK_VIRTUAL, aspeed_timer_expire, t);
463 }
464 
465 static void aspeed_timer_realize(DeviceState *dev, Error **errp)
466 {
467     int i;
468     SysBusDevice *sbd = SYS_BUS_DEVICE(dev);
469     AspeedTimerCtrlState *s = ASPEED_TIMER(dev);
470     Object *obj;
471     Error *err = NULL;
472 
473     obj = object_property_get_link(OBJECT(dev), "scu", &err);
474     if (!obj) {
475         error_propagate_prepend(errp, err, "required link 'scu' not found: ");
476         return;
477     }
478     s->scu = ASPEED_SCU(obj);
479 
480     for (i = 0; i < ASPEED_TIMER_NR_TIMERS; i++) {
481         aspeed_init_one_timer(s, i);
482         sysbus_init_irq(sbd, &s->timers[i].irq);
483     }
484     memory_region_init_io(&s->iomem, OBJECT(s), &aspeed_timer_ops, s,
485                           TYPE_ASPEED_TIMER, 0x1000);
486     sysbus_init_mmio(sbd, &s->iomem);
487 }
488 
489 static void aspeed_timer_reset(DeviceState *dev)
490 {
491     int i;
492     AspeedTimerCtrlState *s = ASPEED_TIMER(dev);
493 
494     for (i = 0; i < ASPEED_TIMER_NR_TIMERS; i++) {
495         AspeedTimer *t = &s->timers[i];
496         /* Explicitly call helpers to avoid any conditional behaviour through
497          * aspeed_timer_set_ctrl().
498          */
499         aspeed_timer_ctrl_enable(t, false);
500         aspeed_timer_ctrl_external_clock(t, TIMER_CLOCK_USE_APB);
501         aspeed_timer_ctrl_overflow_interrupt(t, false);
502         aspeed_timer_ctrl_pulse_enable(t, false);
503         t->level = 0;
504         t->reload = 0;
505         t->match[0] = 0;
506         t->match[1] = 0;
507     }
508     s->ctrl = 0;
509     s->ctrl2 = 0;
510 }
511 
512 static const VMStateDescription vmstate_aspeed_timer = {
513     .name = "aspeed.timer",
514     .version_id = 2,
515     .minimum_version_id = 2,
516     .fields = (VMStateField[]) {
517         VMSTATE_UINT8(id, AspeedTimer),
518         VMSTATE_INT32(level, AspeedTimer),
519         VMSTATE_TIMER(timer, AspeedTimer),
520         VMSTATE_UINT32(reload, AspeedTimer),
521         VMSTATE_UINT32_ARRAY(match, AspeedTimer, 2),
522         VMSTATE_END_OF_LIST()
523     }
524 };
525 
526 static const VMStateDescription vmstate_aspeed_timer_state = {
527     .name = "aspeed.timerctrl",
528     .version_id = 1,
529     .minimum_version_id = 1,
530     .fields = (VMStateField[]) {
531         VMSTATE_UINT32(ctrl, AspeedTimerCtrlState),
532         VMSTATE_UINT32(ctrl2, AspeedTimerCtrlState),
533         VMSTATE_STRUCT_ARRAY(timers, AspeedTimerCtrlState,
534                              ASPEED_TIMER_NR_TIMERS, 1, vmstate_aspeed_timer,
535                              AspeedTimer),
536         VMSTATE_END_OF_LIST()
537     }
538 };
539 
540 static void timer_class_init(ObjectClass *klass, void *data)
541 {
542     DeviceClass *dc = DEVICE_CLASS(klass);
543 
544     dc->realize = aspeed_timer_realize;
545     dc->reset = aspeed_timer_reset;
546     dc->desc = "ASPEED Timer";
547     dc->vmsd = &vmstate_aspeed_timer_state;
548 }
549 
550 static const TypeInfo aspeed_timer_info = {
551     .name = TYPE_ASPEED_TIMER,
552     .parent = TYPE_SYS_BUS_DEVICE,
553     .instance_size = sizeof(AspeedTimerCtrlState),
554     .class_init = timer_class_init,
555 };
556 
557 static void aspeed_timer_register_types(void)
558 {
559     type_register_static(&aspeed_timer_info);
560 }
561 
562 type_init(aspeed_timer_register_types)
563