2 * Intel XScale PXA255/270 OS Timers.
4 * Copyright (c) 2006 Openedhand Ltd.
5 * Copyright (c) 2006 Thorsten Zitterell
7 * This code is licensed under the GPL.
11 #include "qemu-timer.h"
28 #define OSCR 0x10 /* OS Timer Count */
37 #define OSSR 0x14 /* Timer status register */
39 #define OIER 0x1c /* Interrupt enable register 3-0 to E3-E0 */
40 #define OMCR4 0xc0 /* OS Match Control registers */
50 #define PXA25X_FREQ 3686400 /* 3.6864 MHz */
51 #define PXA27X_FREQ 3250000 /* 3.25 MHz */
53 static int pxa2xx_timer4_freq[8] = {
59 /* [5] is the "Externally supplied clock". Assign if necessary. */
63 typedef struct PXA2xxTimerInfo PXA2xxTimerInfo;
70 PXA2xxTimerInfo *info;
82 struct PXA2xxTimerInfo {
91 PXA2xxTimer0 timer[4];
101 #define PXA2XX_TIMER_HAVE_TM4 0
103 static inline int pxa2xx_timer_has_tm4(PXA2xxTimerInfo *s)
105 return s->flags & (1 << PXA2XX_TIMER_HAVE_TM4);
108 static void pxa2xx_timer_update(void *opaque, uint64_t now_qemu)
110 PXA2xxTimerInfo *s = (PXA2xxTimerInfo *) opaque;
116 muldiv64(now_qemu - s->lastload, s->freq, get_ticks_per_sec());
118 for (i = 0; i < 4; i ++) {
119 new_qemu = now_qemu + muldiv64((uint32_t) (s->timer[i].value - now_vm),
120 get_ticks_per_sec(), s->freq);
121 qemu_mod_timer(s->timer[i].qtimer, new_qemu);
125 static void pxa2xx_timer_update4(void *opaque, uint64_t now_qemu, int n)
127 PXA2xxTimerInfo *s = (PXA2xxTimerInfo *) opaque;
130 static const int counters[8] = { 0, 0, 0, 0, 4, 4, 6, 6 };
133 if (s->tm4[n].control & (1 << 7))
136 counter = counters[n];
138 if (!s->tm4[counter].freq) {
139 qemu_del_timer(s->tm4[n].tm.qtimer);
143 now_vm = s->tm4[counter].clock + muldiv64(now_qemu -
144 s->tm4[counter].lastload,
145 s->tm4[counter].freq, get_ticks_per_sec());
147 new_qemu = now_qemu + muldiv64((uint32_t) (s->tm4[n].tm.value - now_vm),
148 get_ticks_per_sec(), s->tm4[counter].freq);
149 qemu_mod_timer(s->tm4[n].tm.qtimer, new_qemu);
152 static uint64_t pxa2xx_timer_read(void *opaque, target_phys_addr_t offset,
155 PXA2xxTimerInfo *s = (PXA2xxTimerInfo *) opaque;
163 return s->timer[tm].value;
172 if (!pxa2xx_timer_has_tm4(s))
174 return s->tm4[tm].tm.value;
176 return s->clock + muldiv64(qemu_get_clock_ns(vm_clock) -
177 s->lastload, s->freq, get_ticks_per_sec());
186 if (!pxa2xx_timer_has_tm4(s))
189 if ((tm == 9 - 4 || tm == 11 - 4) && (s->tm4[tm].control & (1 << 9))) {
190 if (s->tm4[tm - 1].freq)
191 s->snapshot = s->tm4[tm - 1].clock + muldiv64(
192 qemu_get_clock_ns(vm_clock) -
193 s->tm4[tm - 1].lastload,
194 s->tm4[tm - 1].freq, get_ticks_per_sec());
196 s->snapshot = s->tm4[tm - 1].clock;
199 if (!s->tm4[tm].freq)
200 return s->tm4[tm].clock;
201 return s->tm4[tm].clock + muldiv64(qemu_get_clock_ns(vm_clock) -
202 s->tm4[tm].lastload, s->tm4[tm].freq, get_ticks_per_sec());
204 return s->irq_enabled;
205 case OSSR: /* Status register */
217 if (!pxa2xx_timer_has_tm4(s))
219 return s->tm4[tm].control;
224 hw_error("pxa2xx_timer_read: Bad offset " REG_FMT "\n", offset);
230 static void pxa2xx_timer_write(void *opaque, target_phys_addr_t offset,
231 uint64_t value, unsigned size)
234 PXA2xxTimerInfo *s = (PXA2xxTimerInfo *) opaque;
241 s->timer[tm].value = value;
242 pxa2xx_timer_update(s, qemu_get_clock_ns(vm_clock));
252 if (!pxa2xx_timer_has_tm4(s))
254 s->tm4[tm].tm.value = value;
255 pxa2xx_timer_update4(s, qemu_get_clock_ns(vm_clock), tm);
258 s->oldclock = s->clock;
259 s->lastload = qemu_get_clock_ns(vm_clock);
261 pxa2xx_timer_update(s, s->lastload);
271 if (!pxa2xx_timer_has_tm4(s))
273 s->tm4[tm].oldclock = s->tm4[tm].clock;
274 s->tm4[tm].lastload = qemu_get_clock_ns(vm_clock);
275 s->tm4[tm].clock = value;
276 pxa2xx_timer_update4(s, s->tm4[tm].lastload, tm);
279 s->irq_enabled = value & 0xfff;
281 case OSSR: /* Status register */
284 for (i = 0; i < 4; i ++, value >>= 1)
286 qemu_irq_lower(s->timer[i].irq);
287 if (pxa2xx_timer_has_tm4(s) && !(s->events & 0xff0) && value)
288 qemu_irq_lower(s->irq4);
290 case OWER: /* XXX: Reset on OSMR3 match? */
297 if (!pxa2xx_timer_has_tm4(s))
299 s->tm4[tm].control = value & 0x0ff;
300 /* XXX Stop if running (shouldn't happen) */
301 if ((value & (1 << 7)) || tm == 0)
302 s->tm4[tm].freq = pxa2xx_timer4_freq[value & 7];
305 pxa2xx_timer_update4(s, qemu_get_clock_ns(vm_clock), tm);
312 if (!pxa2xx_timer_has_tm4(s))
314 s->tm4[tm].control = value & 0x3ff;
315 /* XXX Stop if running (shouldn't happen) */
316 if ((value & (1 << 7)) || !(tm & 1))
318 pxa2xx_timer4_freq[(value & (1 << 8)) ? 0 : (value & 7)];
321 pxa2xx_timer_update4(s, qemu_get_clock_ns(vm_clock), tm);
326 hw_error("pxa2xx_timer_write: Bad offset " REG_FMT "\n", offset);
330 static const MemoryRegionOps pxa2xx_timer_ops = {
331 .read = pxa2xx_timer_read,
332 .write = pxa2xx_timer_write,
333 .endianness = DEVICE_NATIVE_ENDIAN,
336 static void pxa2xx_timer_tick(void *opaque)
338 PXA2xxTimer0 *t = (PXA2xxTimer0 *) opaque;
339 PXA2xxTimerInfo *i = t->info;
341 if (i->irq_enabled & (1 << t->num)) {
342 i->events |= 1 << t->num;
343 qemu_irq_raise(t->irq);
349 qemu_system_reset_request();
353 static void pxa2xx_timer_tick4(void *opaque)
355 PXA2xxTimer4 *t = (PXA2xxTimer4 *) opaque;
356 PXA2xxTimerInfo *i = (PXA2xxTimerInfo *) t->tm.info;
358 pxa2xx_timer_tick(&t->tm);
359 if (t->control & (1 << 3))
361 if (t->control & (1 << 6))
362 pxa2xx_timer_update4(i, qemu_get_clock_ns(vm_clock), t->tm.num - 4);
363 if (i->events & 0xff0)
364 qemu_irq_raise(i->irq4);
367 static int pxa25x_timer_post_load(void *opaque, int version_id)
369 PXA2xxTimerInfo *s = (PXA2xxTimerInfo *) opaque;
373 now = qemu_get_clock_ns(vm_clock);
374 pxa2xx_timer_update(s, now);
376 if (pxa2xx_timer_has_tm4(s))
377 for (i = 0; i < 8; i ++)
378 pxa2xx_timer_update4(s, now, i);
383 static int pxa2xx_timer_init(SysBusDevice *dev)
388 s = FROM_SYSBUS(PXA2xxTimerInfo, dev);
392 s->lastload = qemu_get_clock_ns(vm_clock);
395 for (i = 0; i < 4; i ++) {
396 s->timer[i].value = 0;
397 sysbus_init_irq(dev, &s->timer[i].irq);
398 s->timer[i].info = s;
400 s->timer[i].qtimer = qemu_new_timer_ns(vm_clock,
401 pxa2xx_timer_tick, &s->timer[i]);
403 if (s->flags & (1 << PXA2XX_TIMER_HAVE_TM4)) {
404 sysbus_init_irq(dev, &s->irq4);
406 for (i = 0; i < 8; i ++) {
407 s->tm4[i].tm.value = 0;
408 s->tm4[i].tm.info = s;
409 s->tm4[i].tm.num = i + 4;
411 s->tm4[i].control = 0x0;
412 s->tm4[i].tm.qtimer = qemu_new_timer_ns(vm_clock,
413 pxa2xx_timer_tick4, &s->tm4[i]);
417 memory_region_init_io(&s->iomem, &pxa2xx_timer_ops, s,
418 "pxa2xx-timer", 0x00001000);
419 sysbus_init_mmio(dev, &s->iomem);
424 static const VMStateDescription vmstate_pxa2xx_timer0_regs = {
425 .name = "pxa2xx_timer0",
427 .minimum_version_id = 2,
428 .minimum_version_id_old = 2,
429 .fields = (VMStateField[]) {
430 VMSTATE_UINT32(value, PXA2xxTimer0),
431 VMSTATE_END_OF_LIST(),
435 static const VMStateDescription vmstate_pxa2xx_timer4_regs = {
436 .name = "pxa2xx_timer4",
438 .minimum_version_id = 1,
439 .minimum_version_id_old = 1,
440 .fields = (VMStateField[]) {
441 VMSTATE_STRUCT(tm, PXA2xxTimer4, 1,
442 vmstate_pxa2xx_timer0_regs, PXA2xxTimer0),
443 VMSTATE_INT32(oldclock, PXA2xxTimer4),
444 VMSTATE_INT32(clock, PXA2xxTimer4),
445 VMSTATE_UINT64(lastload, PXA2xxTimer4),
446 VMSTATE_UINT32(freq, PXA2xxTimer4),
447 VMSTATE_UINT32(control, PXA2xxTimer4),
448 VMSTATE_END_OF_LIST(),
452 static bool pxa2xx_timer_has_tm4_test(void *opaque, int version_id)
454 return pxa2xx_timer_has_tm4(opaque);
457 static const VMStateDescription vmstate_pxa2xx_timer_regs = {
458 .name = "pxa2xx_timer",
460 .minimum_version_id = 1,
461 .minimum_version_id_old = 1,
462 .post_load = pxa25x_timer_post_load,
463 .fields = (VMStateField[]) {
464 VMSTATE_INT32(clock, PXA2xxTimerInfo),
465 VMSTATE_INT32(oldclock, PXA2xxTimerInfo),
466 VMSTATE_UINT64(lastload, PXA2xxTimerInfo),
467 VMSTATE_STRUCT_ARRAY(timer, PXA2xxTimerInfo, 4, 1,
468 vmstate_pxa2xx_timer0_regs, PXA2xxTimer0),
469 VMSTATE_UINT32(events, PXA2xxTimerInfo),
470 VMSTATE_UINT32(irq_enabled, PXA2xxTimerInfo),
471 VMSTATE_UINT32(reset3, PXA2xxTimerInfo),
472 VMSTATE_UINT32(snapshot, PXA2xxTimerInfo),
473 VMSTATE_STRUCT_ARRAY_TEST(tm4, PXA2xxTimerInfo, 8,
474 pxa2xx_timer_has_tm4_test, 0,
475 vmstate_pxa2xx_timer4_regs, PXA2xxTimer4),
476 VMSTATE_END_OF_LIST(),
480 static Property pxa25x_timer_dev_properties[] = {
481 DEFINE_PROP_UINT32("freq", PXA2xxTimerInfo, freq, PXA25X_FREQ),
482 DEFINE_PROP_BIT("tm4", PXA2xxTimerInfo, flags,
483 PXA2XX_TIMER_HAVE_TM4, false),
484 DEFINE_PROP_END_OF_LIST(),
487 static void pxa25x_timer_dev_class_init(ObjectClass *klass, void *data)
489 DeviceClass *dc = DEVICE_CLASS(klass);
490 SysBusDeviceClass *k = SYS_BUS_DEVICE_CLASS(klass);
492 k->init = pxa2xx_timer_init;
493 dc->desc = "PXA25x timer";
494 dc->vmsd = &vmstate_pxa2xx_timer_regs;
495 dc->props = pxa25x_timer_dev_properties;
498 static TypeInfo pxa25x_timer_dev_info = {
499 .name = "pxa25x-timer",
500 .parent = TYPE_SYS_BUS_DEVICE,
501 .instance_size = sizeof(PXA2xxTimerInfo),
502 .class_init = pxa25x_timer_dev_class_init,
505 static Property pxa27x_timer_dev_properties[] = {
506 DEFINE_PROP_UINT32("freq", PXA2xxTimerInfo, freq, PXA27X_FREQ),
507 DEFINE_PROP_BIT("tm4", PXA2xxTimerInfo, flags,
508 PXA2XX_TIMER_HAVE_TM4, true),
509 DEFINE_PROP_END_OF_LIST(),
512 static void pxa27x_timer_dev_class_init(ObjectClass *klass, void *data)
514 DeviceClass *dc = DEVICE_CLASS(klass);
515 SysBusDeviceClass *k = SYS_BUS_DEVICE_CLASS(klass);
517 k->init = pxa2xx_timer_init;
518 dc->desc = "PXA27x timer";
519 dc->vmsd = &vmstate_pxa2xx_timer_regs;
520 dc->props = pxa27x_timer_dev_properties;
523 static TypeInfo pxa27x_timer_dev_info = {
524 .name = "pxa27x-timer",
525 .parent = TYPE_SYS_BUS_DEVICE,
526 .instance_size = sizeof(PXA2xxTimerInfo),
527 .class_init = pxa27x_timer_dev_class_init,
530 static void pxa2xx_timer_register(void)
532 type_register_static(&pxa25x_timer_dev_info);
533 type_register_static(&pxa27x_timer_dev_info);
535 device_init(pxa2xx_timer_register);