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