xref: /openbmc/qemu/hw/timer/pxa2xx_timer.c (revision a68694cd)
1 /*
2  * Intel XScale PXA255/270 OS Timers.
3  *
4  * Copyright (c) 2006 Openedhand Ltd.
5  * Copyright (c) 2006 Thorsten Zitterell
6  *
7  * This code is licensed under the GPL.
8  */
9 
10 #include "qemu/osdep.h"
11 #include "hw/irq.h"
12 #include "hw/qdev-properties.h"
13 #include "qemu/timer.h"
14 #include "sysemu/runstate.h"
15 #include "hw/arm/pxa.h"
16 #include "hw/sysbus.h"
17 #include "migration/vmstate.h"
18 #include "qemu/log.h"
19 #include "qemu/module.h"
20 #include "qom/object.h"
21 
22 #define OSMR0	0x00
23 #define OSMR1	0x04
24 #define OSMR2	0x08
25 #define OSMR3	0x0c
26 #define OSMR4	0x80
27 #define OSMR5	0x84
28 #define OSMR6	0x88
29 #define OSMR7	0x8c
30 #define OSMR8	0x90
31 #define OSMR9	0x94
32 #define OSMR10	0x98
33 #define OSMR11	0x9c
34 #define OSCR	0x10	/* OS Timer Count */
35 #define OSCR4	0x40
36 #define OSCR5	0x44
37 #define OSCR6	0x48
38 #define OSCR7	0x4c
39 #define OSCR8	0x50
40 #define OSCR9	0x54
41 #define OSCR10	0x58
42 #define OSCR11	0x5c
43 #define OSSR	0x14	/* Timer status register */
44 #define OWER	0x18
45 #define OIER	0x1c	/* Interrupt enable register  3-0 to E3-E0 */
46 #define OMCR4	0xc0	/* OS Match Control registers */
47 #define OMCR5	0xc4
48 #define OMCR6	0xc8
49 #define OMCR7	0xcc
50 #define OMCR8	0xd0
51 #define OMCR9	0xd4
52 #define OMCR10	0xd8
53 #define OMCR11	0xdc
54 #define OSNR	0x20
55 
56 #define PXA25X_FREQ	3686400	/* 3.6864 MHz */
57 #define PXA27X_FREQ	3250000	/* 3.25 MHz */
58 
59 static int pxa2xx_timer4_freq[8] = {
60     [0] = 0,
61     [1] = 32768,
62     [2] = 1000,
63     [3] = 1,
64     [4] = 1000000,
65     /* [5] is the "Externally supplied clock".  Assign if necessary.  */
66     [5 ... 7] = 0,
67 };
68 
69 #define TYPE_PXA2XX_TIMER "pxa2xx-timer"
70 typedef struct PXA2xxTimerInfo PXA2xxTimerInfo;
71 DECLARE_INSTANCE_CHECKER(PXA2xxTimerInfo, PXA2XX_TIMER,
72                          TYPE_PXA2XX_TIMER)
73 
74 
75 typedef struct {
76     uint32_t value;
77     qemu_irq irq;
78     QEMUTimer *qtimer;
79     int num;
80     PXA2xxTimerInfo *info;
81 } PXA2xxTimer0;
82 
83 typedef struct {
84     PXA2xxTimer0 tm;
85     int32_t oldclock;
86     int32_t clock;
87     uint64_t lastload;
88     uint32_t freq;
89     uint32_t control;
90 } PXA2xxTimer4;
91 
92 struct PXA2xxTimerInfo {
93     SysBusDevice parent_obj;
94 
95     MemoryRegion iomem;
96     uint32_t flags;
97 
98     int32_t clock;
99     int32_t oldclock;
100     uint64_t lastload;
101     uint32_t freq;
102     PXA2xxTimer0 timer[4];
103     uint32_t events;
104     uint32_t irq_enabled;
105     uint32_t reset3;
106     uint32_t snapshot;
107 
108     qemu_irq irq4;
109     PXA2xxTimer4 tm4[8];
110 };
111 
112 #define PXA2XX_TIMER_HAVE_TM4	0
113 
114 static inline int pxa2xx_timer_has_tm4(PXA2xxTimerInfo *s)
115 {
116     return s->flags & (1 << PXA2XX_TIMER_HAVE_TM4);
117 }
118 
119 static void pxa2xx_timer_update(void *opaque, uint64_t now_qemu)
120 {
121     PXA2xxTimerInfo *s = (PXA2xxTimerInfo *) opaque;
122     int i;
123     uint32_t now_vm;
124     uint64_t new_qemu;
125 
126     now_vm = s->clock +
127             muldiv64(now_qemu - s->lastload, s->freq, NANOSECONDS_PER_SECOND);
128 
129     for (i = 0; i < 4; i ++) {
130         new_qemu = now_qemu + muldiv64((uint32_t) (s->timer[i].value - now_vm),
131                         NANOSECONDS_PER_SECOND, s->freq);
132         timer_mod(s->timer[i].qtimer, new_qemu);
133     }
134 }
135 
136 static void pxa2xx_timer_update4(void *opaque, uint64_t now_qemu, int n)
137 {
138     PXA2xxTimerInfo *s = (PXA2xxTimerInfo *) opaque;
139     uint32_t now_vm;
140     uint64_t new_qemu;
141     static const int counters[8] = { 0, 0, 0, 0, 4, 4, 6, 6 };
142     int counter;
143 
144     assert(n < ARRAY_SIZE(counters));
145     if (s->tm4[n].control & (1 << 7))
146         counter = n;
147     else
148         counter = counters[n];
149 
150     if (!s->tm4[counter].freq) {
151         timer_del(s->tm4[n].tm.qtimer);
152         return;
153     }
154 
155     now_vm = s->tm4[counter].clock + muldiv64(now_qemu -
156                     s->tm4[counter].lastload,
157                     s->tm4[counter].freq, NANOSECONDS_PER_SECOND);
158 
159     new_qemu = now_qemu + muldiv64((uint32_t) (s->tm4[n].tm.value - now_vm),
160                     NANOSECONDS_PER_SECOND, s->tm4[counter].freq);
161     timer_mod(s->tm4[n].tm.qtimer, new_qemu);
162 }
163 
164 static uint64_t pxa2xx_timer_read(void *opaque, hwaddr offset,
165                                   unsigned size)
166 {
167     PXA2xxTimerInfo *s = (PXA2xxTimerInfo *) opaque;
168     int tm = 0;
169 
170     switch (offset) {
171     case OSMR3:  tm ++;
172         /* fall through */
173     case OSMR2:  tm ++;
174         /* fall through */
175     case OSMR1:  tm ++;
176         /* fall through */
177     case OSMR0:
178         return s->timer[tm].value;
179     case OSMR11: tm ++;
180         /* fall through */
181     case OSMR10: tm ++;
182         /* fall through */
183     case OSMR9:  tm ++;
184         /* fall through */
185     case OSMR8:  tm ++;
186         /* fall through */
187     case OSMR7:  tm ++;
188         /* fall through */
189     case OSMR6:  tm ++;
190         /* fall through */
191     case OSMR5:  tm ++;
192         /* fall through */
193     case OSMR4:
194         if (!pxa2xx_timer_has_tm4(s))
195             goto badreg;
196         return s->tm4[tm].tm.value;
197     case OSCR:
198         return s->clock + muldiv64(qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL) -
199                         s->lastload, s->freq, NANOSECONDS_PER_SECOND);
200     case OSCR11: tm ++;
201         /* fall through */
202     case OSCR10: tm ++;
203         /* fall through */
204     case OSCR9:  tm ++;
205         /* fall through */
206     case OSCR8:  tm ++;
207         /* fall through */
208     case OSCR7:  tm ++;
209         /* fall through */
210     case OSCR6:  tm ++;
211         /* fall through */
212     case OSCR5:  tm ++;
213         /* fall through */
214     case OSCR4:
215         if (!pxa2xx_timer_has_tm4(s))
216             goto badreg;
217 
218         if ((tm == 9 - 4 || tm == 11 - 4) && (s->tm4[tm].control & (1 << 9))) {
219             if (s->tm4[tm - 1].freq)
220                 s->snapshot = s->tm4[tm - 1].clock + muldiv64(
221                                 qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL) -
222                                 s->tm4[tm - 1].lastload,
223                                 s->tm4[tm - 1].freq, NANOSECONDS_PER_SECOND);
224             else
225                 s->snapshot = s->tm4[tm - 1].clock;
226         }
227 
228         if (!s->tm4[tm].freq)
229             return s->tm4[tm].clock;
230         return s->tm4[tm].clock +
231             muldiv64(qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL) -
232                      s->tm4[tm].lastload, s->tm4[tm].freq,
233                      NANOSECONDS_PER_SECOND);
234     case OIER:
235         return s->irq_enabled;
236     case OSSR:	/* Status register */
237         return s->events;
238     case OWER:
239         return s->reset3;
240     case OMCR11: tm ++;
241         /* fall through */
242     case OMCR10: tm ++;
243         /* fall through */
244     case OMCR9:  tm ++;
245         /* fall through */
246     case OMCR8:  tm ++;
247         /* fall through */
248     case OMCR7:  tm ++;
249         /* fall through */
250     case OMCR6:  tm ++;
251         /* fall through */
252     case OMCR5:  tm ++;
253         /* fall through */
254     case OMCR4:
255         if (!pxa2xx_timer_has_tm4(s))
256             goto badreg;
257         return s->tm4[tm].control;
258     case OSNR:
259         return s->snapshot;
260     default:
261         qemu_log_mask(LOG_UNIMP,
262                       "%s: unknown register 0x%02" HWADDR_PRIx "\n",
263                       __func__, offset);
264         break;
265     badreg:
266         qemu_log_mask(LOG_GUEST_ERROR,
267                       "%s: incorrect register 0x%02" HWADDR_PRIx "\n",
268                       __func__, offset);
269     }
270 
271     return 0;
272 }
273 
274 static void pxa2xx_timer_write(void *opaque, hwaddr offset,
275                                uint64_t value, unsigned size)
276 {
277     int i, tm = 0;
278     PXA2xxTimerInfo *s = (PXA2xxTimerInfo *) opaque;
279 
280     switch (offset) {
281     case OSMR3:  tm ++;
282         /* fall through */
283     case OSMR2:  tm ++;
284         /* fall through */
285     case OSMR1:  tm ++;
286         /* fall through */
287     case OSMR0:
288         s->timer[tm].value = value;
289         pxa2xx_timer_update(s, qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL));
290         break;
291     case OSMR11: tm ++;
292         /* fall through */
293     case OSMR10: tm ++;
294         /* fall through */
295     case OSMR9:  tm ++;
296         /* fall through */
297     case OSMR8:  tm ++;
298         /* fall through */
299     case OSMR7:  tm ++;
300         /* fall through */
301     case OSMR6:  tm ++;
302         /* fall through */
303     case OSMR5:  tm ++;
304         /* fall through */
305     case OSMR4:
306         if (!pxa2xx_timer_has_tm4(s))
307             goto badreg;
308         s->tm4[tm].tm.value = value;
309         pxa2xx_timer_update4(s, qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL), tm);
310         break;
311     case OSCR:
312         s->oldclock = s->clock;
313         s->lastload = qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL);
314         s->clock = value;
315         pxa2xx_timer_update(s, s->lastload);
316         break;
317     case OSCR11: tm ++;
318         /* fall through */
319     case OSCR10: tm ++;
320         /* fall through */
321     case OSCR9:  tm ++;
322         /* fall through */
323     case OSCR8:  tm ++;
324         /* fall through */
325     case OSCR7:  tm ++;
326         /* fall through */
327     case OSCR6:  tm ++;
328         /* fall through */
329     case OSCR5:  tm ++;
330         /* fall through */
331     case OSCR4:
332         if (!pxa2xx_timer_has_tm4(s))
333             goto badreg;
334         s->tm4[tm].oldclock = s->tm4[tm].clock;
335         s->tm4[tm].lastload = qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL);
336         s->tm4[tm].clock = value;
337         pxa2xx_timer_update4(s, s->tm4[tm].lastload, tm);
338         break;
339     case OIER:
340         s->irq_enabled = value & 0xfff;
341         break;
342     case OSSR:	/* Status register */
343         value &= s->events;
344         s->events &= ~value;
345         for (i = 0; i < 4; i ++, value >>= 1)
346             if (value & 1)
347                 qemu_irq_lower(s->timer[i].irq);
348         if (pxa2xx_timer_has_tm4(s) && !(s->events & 0xff0) && value)
349             qemu_irq_lower(s->irq4);
350         break;
351     case OWER:	/* XXX: Reset on OSMR3 match? */
352         s->reset3 = value;
353         break;
354     case OMCR7:  tm ++;
355         /* fall through */
356     case OMCR6:  tm ++;
357         /* fall through */
358     case OMCR5:  tm ++;
359         /* fall through */
360     case OMCR4:
361         if (!pxa2xx_timer_has_tm4(s))
362             goto badreg;
363         s->tm4[tm].control = value & 0x0ff;
364         /* XXX Stop if running (shouldn't happen) */
365         if ((value & (1 << 7)) || tm == 0)
366             s->tm4[tm].freq = pxa2xx_timer4_freq[value & 7];
367         else {
368             s->tm4[tm].freq = 0;
369             pxa2xx_timer_update4(s, qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL), tm);
370         }
371         break;
372     case OMCR11: tm ++;
373         /* fall through */
374     case OMCR10: tm ++;
375         /* fall through */
376     case OMCR9:  tm ++;
377         /* fall through */
378     case OMCR8:  tm += 4;
379         if (!pxa2xx_timer_has_tm4(s))
380             goto badreg;
381         s->tm4[tm].control = value & 0x3ff;
382         /* XXX Stop if running (shouldn't happen) */
383         if ((value & (1 << 7)) || !(tm & 1))
384             s->tm4[tm].freq =
385                     pxa2xx_timer4_freq[(value & (1 << 8)) ?  0 : (value & 7)];
386         else {
387             s->tm4[tm].freq = 0;
388             pxa2xx_timer_update4(s, qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL), tm);
389         }
390         break;
391     default:
392         qemu_log_mask(LOG_UNIMP,
393                       "%s: unknown register 0x%02" HWADDR_PRIx " "
394                       "(value 0x%08" PRIx64 ")\n",  __func__, offset, value);
395         break;
396     badreg:
397         qemu_log_mask(LOG_GUEST_ERROR,
398                       "%s: incorrect register 0x%02" HWADDR_PRIx " "
399                       "(value 0x%08" PRIx64 ")\n", __func__, offset, value);
400     }
401 }
402 
403 static const MemoryRegionOps pxa2xx_timer_ops = {
404     .read = pxa2xx_timer_read,
405     .write = pxa2xx_timer_write,
406     .endianness = DEVICE_NATIVE_ENDIAN,
407 };
408 
409 static void pxa2xx_timer_tick(void *opaque)
410 {
411     PXA2xxTimer0 *t = (PXA2xxTimer0 *) opaque;
412     PXA2xxTimerInfo *i = t->info;
413 
414     if (i->irq_enabled & (1 << t->num)) {
415         i->events |= 1 << t->num;
416         qemu_irq_raise(t->irq);
417     }
418 
419     if (t->num == 3)
420         if (i->reset3 & 1) {
421             i->reset3 = 0;
422             qemu_system_reset_request(SHUTDOWN_CAUSE_GUEST_RESET);
423         }
424 }
425 
426 static void pxa2xx_timer_tick4(void *opaque)
427 {
428     PXA2xxTimer4 *t = (PXA2xxTimer4 *) opaque;
429     PXA2xxTimerInfo *i = (PXA2xxTimerInfo *) t->tm.info;
430 
431     pxa2xx_timer_tick(&t->tm);
432     if (t->control & (1 << 3))
433         t->clock = 0;
434     if (t->control & (1 << 6))
435         pxa2xx_timer_update4(i, qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL), t->tm.num - 4);
436     if (i->events & 0xff0)
437         qemu_irq_raise(i->irq4);
438 }
439 
440 static int pxa25x_timer_post_load(void *opaque, int version_id)
441 {
442     PXA2xxTimerInfo *s = (PXA2xxTimerInfo *) opaque;
443     int64_t now;
444     int i;
445 
446     now = qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL);
447     pxa2xx_timer_update(s, now);
448 
449     if (pxa2xx_timer_has_tm4(s))
450         for (i = 0; i < 8; i ++)
451             pxa2xx_timer_update4(s, now, i);
452 
453     return 0;
454 }
455 
456 static void pxa2xx_timer_init(Object *obj)
457 {
458     PXA2xxTimerInfo *s = PXA2XX_TIMER(obj);
459     SysBusDevice *dev = SYS_BUS_DEVICE(obj);
460 
461     s->irq_enabled = 0;
462     s->oldclock = 0;
463     s->clock = 0;
464     s->lastload = qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL);
465     s->reset3 = 0;
466 
467     memory_region_init_io(&s->iomem, obj, &pxa2xx_timer_ops, s,
468                           "pxa2xx-timer", 0x00001000);
469     sysbus_init_mmio(dev, &s->iomem);
470 }
471 
472 static void pxa2xx_timer_realize(DeviceState *dev, Error **errp)
473 {
474     PXA2xxTimerInfo *s = PXA2XX_TIMER(dev);
475     SysBusDevice *sbd = SYS_BUS_DEVICE(dev);
476     int i;
477 
478     for (i = 0; i < 4; i ++) {
479         s->timer[i].value = 0;
480         sysbus_init_irq(sbd, &s->timer[i].irq);
481         s->timer[i].info = s;
482         s->timer[i].num = i;
483         s->timer[i].qtimer = timer_new_ns(QEMU_CLOCK_VIRTUAL,
484                                           pxa2xx_timer_tick, &s->timer[i]);
485     }
486 
487     if (s->flags & (1 << PXA2XX_TIMER_HAVE_TM4)) {
488         sysbus_init_irq(sbd, &s->irq4);
489 
490         for (i = 0; i < 8; i ++) {
491             s->tm4[i].tm.value = 0;
492             s->tm4[i].tm.info = s;
493             s->tm4[i].tm.num = i + 4;
494             s->tm4[i].freq = 0;
495             s->tm4[i].control = 0x0;
496             s->tm4[i].tm.qtimer = timer_new_ns(QEMU_CLOCK_VIRTUAL,
497                                                pxa2xx_timer_tick4, &s->tm4[i]);
498         }
499     }
500 }
501 
502 static const VMStateDescription vmstate_pxa2xx_timer0_regs = {
503     .name = "pxa2xx_timer0",
504     .version_id = 2,
505     .minimum_version_id = 2,
506     .fields = (VMStateField[]) {
507         VMSTATE_UINT32(value, PXA2xxTimer0),
508         VMSTATE_END_OF_LIST(),
509     },
510 };
511 
512 static const VMStateDescription vmstate_pxa2xx_timer4_regs = {
513     .name = "pxa2xx_timer4",
514     .version_id = 1,
515     .minimum_version_id = 1,
516     .fields = (VMStateField[]) {
517         VMSTATE_STRUCT(tm, PXA2xxTimer4, 1,
518                         vmstate_pxa2xx_timer0_regs, PXA2xxTimer0),
519         VMSTATE_INT32(oldclock, PXA2xxTimer4),
520         VMSTATE_INT32(clock, PXA2xxTimer4),
521         VMSTATE_UINT64(lastload, PXA2xxTimer4),
522         VMSTATE_UINT32(freq, PXA2xxTimer4),
523         VMSTATE_UINT32(control, PXA2xxTimer4),
524         VMSTATE_END_OF_LIST(),
525     },
526 };
527 
528 static bool pxa2xx_timer_has_tm4_test(void *opaque, int version_id)
529 {
530     return pxa2xx_timer_has_tm4(opaque);
531 }
532 
533 static const VMStateDescription vmstate_pxa2xx_timer_regs = {
534     .name = "pxa2xx_timer",
535     .version_id = 1,
536     .minimum_version_id = 1,
537     .post_load = pxa25x_timer_post_load,
538     .fields = (VMStateField[]) {
539         VMSTATE_INT32(clock, PXA2xxTimerInfo),
540         VMSTATE_INT32(oldclock, PXA2xxTimerInfo),
541         VMSTATE_UINT64(lastload, PXA2xxTimerInfo),
542         VMSTATE_STRUCT_ARRAY(timer, PXA2xxTimerInfo, 4, 1,
543                         vmstate_pxa2xx_timer0_regs, PXA2xxTimer0),
544         VMSTATE_UINT32(events, PXA2xxTimerInfo),
545         VMSTATE_UINT32(irq_enabled, PXA2xxTimerInfo),
546         VMSTATE_UINT32(reset3, PXA2xxTimerInfo),
547         VMSTATE_UINT32(snapshot, PXA2xxTimerInfo),
548         VMSTATE_STRUCT_ARRAY_TEST(tm4, PXA2xxTimerInfo, 8,
549                         pxa2xx_timer_has_tm4_test, 0,
550                         vmstate_pxa2xx_timer4_regs, PXA2xxTimer4),
551         VMSTATE_END_OF_LIST(),
552     }
553 };
554 
555 static Property pxa25x_timer_dev_properties[] = {
556     DEFINE_PROP_UINT32("freq", PXA2xxTimerInfo, freq, PXA25X_FREQ),
557     DEFINE_PROP_BIT("tm4", PXA2xxTimerInfo, flags,
558                     PXA2XX_TIMER_HAVE_TM4, false),
559     DEFINE_PROP_END_OF_LIST(),
560 };
561 
562 static void pxa25x_timer_dev_class_init(ObjectClass *klass, void *data)
563 {
564     DeviceClass *dc = DEVICE_CLASS(klass);
565 
566     dc->desc = "PXA25x timer";
567     device_class_set_props(dc, pxa25x_timer_dev_properties);
568 }
569 
570 static const TypeInfo pxa25x_timer_dev_info = {
571     .name          = "pxa25x-timer",
572     .parent        = TYPE_PXA2XX_TIMER,
573     .instance_size = sizeof(PXA2xxTimerInfo),
574     .class_init    = pxa25x_timer_dev_class_init,
575 };
576 
577 static Property pxa27x_timer_dev_properties[] = {
578     DEFINE_PROP_UINT32("freq", PXA2xxTimerInfo, freq, PXA27X_FREQ),
579     DEFINE_PROP_BIT("tm4", PXA2xxTimerInfo, flags,
580                     PXA2XX_TIMER_HAVE_TM4, true),
581     DEFINE_PROP_END_OF_LIST(),
582 };
583 
584 static void pxa27x_timer_dev_class_init(ObjectClass *klass, void *data)
585 {
586     DeviceClass *dc = DEVICE_CLASS(klass);
587 
588     dc->desc = "PXA27x timer";
589     device_class_set_props(dc, pxa27x_timer_dev_properties);
590 }
591 
592 static const TypeInfo pxa27x_timer_dev_info = {
593     .name          = "pxa27x-timer",
594     .parent        = TYPE_PXA2XX_TIMER,
595     .instance_size = sizeof(PXA2xxTimerInfo),
596     .class_init    = pxa27x_timer_dev_class_init,
597 };
598 
599 static void pxa2xx_timer_class_init(ObjectClass *oc, void *data)
600 {
601     DeviceClass *dc = DEVICE_CLASS(oc);
602 
603     dc->realize  = pxa2xx_timer_realize;
604     dc->vmsd = &vmstate_pxa2xx_timer_regs;
605 }
606 
607 static const TypeInfo pxa2xx_timer_type_info = {
608     .name          = TYPE_PXA2XX_TIMER,
609     .parent        = TYPE_SYS_BUS_DEVICE,
610     .instance_size = sizeof(PXA2xxTimerInfo),
611     .instance_init = pxa2xx_timer_init,
612     .abstract      = true,
613     .class_init    = pxa2xx_timer_class_init,
614 };
615 
616 static void pxa2xx_timer_register_types(void)
617 {
618     type_register_static(&pxa2xx_timer_type_info);
619     type_register_static(&pxa25x_timer_dev_info);
620     type_register_static(&pxa27x_timer_dev_info);
621 }
622 
623 type_init(pxa2xx_timer_register_types)
624