01cfc4fab999421d14c1c805e2f705c6ec02da00
[qemu] / hw / pxa2xx_timer.c
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 licenced under the GPL.
8  */
9
10 #include "hw.h"
11 #include "qemu-timer.h"
12 #include "sysemu.h"
13 #include "pxa.h"
14
15 #define OSMR0   0x00
16 #define OSMR1   0x04
17 #define OSMR2   0x08
18 #define OSMR3   0x0c
19 #define OSMR4   0x80
20 #define OSMR5   0x84
21 #define OSMR6   0x88
22 #define OSMR7   0x8c
23 #define OSMR8   0x90
24 #define OSMR9   0x94
25 #define OSMR10  0x98
26 #define OSMR11  0x9c
27 #define OSCR    0x10    /* OS Timer Count */
28 #define OSCR4   0x40
29 #define OSCR5   0x44
30 #define OSCR6   0x48
31 #define OSCR7   0x4c
32 #define OSCR8   0x50
33 #define OSCR9   0x54
34 #define OSCR10  0x58
35 #define OSCR11  0x5c
36 #define OSSR    0x14    /* Timer status register */
37 #define OWER    0x18
38 #define OIER    0x1c    /* Interrupt enable register  3-0 to E3-E0 */
39 #define OMCR4   0xc0    /* OS Match Control registers */
40 #define OMCR5   0xc4
41 #define OMCR6   0xc8
42 #define OMCR7   0xcc
43 #define OMCR8   0xd0
44 #define OMCR9   0xd4
45 #define OMCR10  0xd8
46 #define OMCR11  0xdc
47 #define OSNR    0x20
48
49 #define PXA25X_FREQ     3686400 /* 3.6864 MHz */
50 #define PXA27X_FREQ     3250000 /* 3.25 MHz */
51
52 static int pxa2xx_timer4_freq[8] = {
53     [0] = 0,
54     [1] = 32768,
55     [2] = 1000,
56     [3] = 1,
57     [4] = 1000000,
58     /* [5] is the "Externally supplied clock".  Assign if necessary.  */
59     [5 ... 7] = 0,
60 };
61
62 struct pxa2xx_timer0_s {
63     uint32_t value;
64     int level;
65     qemu_irq irq;
66     QEMUTimer *qtimer;
67     int num;
68     void *info;
69 };
70
71 struct pxa2xx_timer4_s {
72     struct pxa2xx_timer0_s tm;
73     int32_t oldclock;
74     int32_t clock;
75     uint64_t lastload;
76     uint32_t freq;
77     uint32_t control;
78 };
79
80 typedef struct {
81     target_phys_addr_t base;
82     int32_t clock;
83     int32_t oldclock;
84     uint64_t lastload;
85     uint32_t freq;
86     struct pxa2xx_timer0_s timer[4];
87     struct pxa2xx_timer4_s *tm4;
88     uint32_t events;
89     uint32_t irq_enabled;
90     uint32_t reset3;
91     uint32_t snapshot;
92 } pxa2xx_timer_info;
93
94 static void pxa2xx_timer_update(void *opaque, uint64_t now_qemu)
95 {
96     pxa2xx_timer_info *s = (pxa2xx_timer_info *) opaque;
97     int i;
98     uint32_t now_vm;
99     uint64_t new_qemu;
100
101     now_vm = s->clock +
102             muldiv64(now_qemu - s->lastload, s->freq, ticks_per_sec);
103
104     for (i = 0; i < 4; i ++) {
105         new_qemu = now_qemu + muldiv64((uint32_t) (s->timer[i].value - now_vm),
106                         ticks_per_sec, s->freq);
107         qemu_mod_timer(s->timer[i].qtimer, new_qemu);
108     }
109 }
110
111 static void pxa2xx_timer_update4(void *opaque, uint64_t now_qemu, int n)
112 {
113     pxa2xx_timer_info *s = (pxa2xx_timer_info *) opaque;
114     uint32_t now_vm;
115     uint64_t new_qemu;
116     static const int counters[8] = { 0, 0, 0, 0, 4, 4, 6, 6 };
117     int counter;
118
119     if (s->tm4[n].control & (1 << 7))
120         counter = n;
121     else
122         counter = counters[n];
123
124     if (!s->tm4[counter].freq) {
125         qemu_del_timer(s->tm4[n].tm.qtimer);
126         return;
127     }
128
129     now_vm = s->tm4[counter].clock + muldiv64(now_qemu -
130                     s->tm4[counter].lastload,
131                     s->tm4[counter].freq, ticks_per_sec);
132
133     new_qemu = now_qemu + muldiv64((uint32_t) (s->tm4[n].tm.value - now_vm),
134                     ticks_per_sec, s->tm4[counter].freq);
135     qemu_mod_timer(s->tm4[n].tm.qtimer, new_qemu);
136 }
137
138 static uint32_t pxa2xx_timer_read(void *opaque, target_phys_addr_t offset)
139 {
140     pxa2xx_timer_info *s = (pxa2xx_timer_info *) opaque;
141     int tm = 0;
142
143     offset -= s->base;
144
145     switch (offset) {
146     case OSMR3:  tm ++;
147     case OSMR2:  tm ++;
148     case OSMR1:  tm ++;
149     case OSMR0:
150         return s->timer[tm].value;
151     case OSMR11: tm ++;
152     case OSMR10: tm ++;
153     case OSMR9:  tm ++;
154     case OSMR8:  tm ++;
155     case OSMR7:  tm ++;
156     case OSMR6:  tm ++;
157     case OSMR5:  tm ++;
158     case OSMR4:
159         if (!s->tm4)
160             goto badreg;
161         return s->tm4[tm].tm.value;
162     case OSCR:
163         return s->clock + muldiv64(qemu_get_clock(vm_clock) -
164                         s->lastload, s->freq, ticks_per_sec);
165     case OSCR11: tm ++;
166     case OSCR10: tm ++;
167     case OSCR9:  tm ++;
168     case OSCR8:  tm ++;
169     case OSCR7:  tm ++;
170     case OSCR6:  tm ++;
171     case OSCR5:  tm ++;
172     case OSCR4:
173         if (!s->tm4)
174             goto badreg;
175
176         if ((tm == 9 - 4 || tm == 11 - 4) && (s->tm4[tm].control & (1 << 9))) {
177             if (s->tm4[tm - 1].freq)
178                 s->snapshot = s->tm4[tm - 1].clock + muldiv64(
179                                 qemu_get_clock(vm_clock) -
180                                 s->tm4[tm - 1].lastload,
181                                 s->tm4[tm - 1].freq, ticks_per_sec);
182             else
183                 s->snapshot = s->tm4[tm - 1].clock;
184         }
185
186         if (!s->tm4[tm].freq)
187             return s->tm4[tm].clock;
188         return s->tm4[tm].clock + muldiv64(qemu_get_clock(vm_clock) -
189                         s->tm4[tm].lastload, s->tm4[tm].freq, ticks_per_sec);
190     case OIER:
191         return s->irq_enabled;
192     case OSSR:  /* Status register */
193         return s->events;
194     case OWER:
195         return s->reset3;
196     case OMCR11: tm ++;
197     case OMCR10: tm ++;
198     case OMCR9:  tm ++;
199     case OMCR8:  tm ++;
200     case OMCR7:  tm ++;
201     case OMCR6:  tm ++;
202     case OMCR5:  tm ++;
203     case OMCR4:
204         if (!s->tm4)
205             goto badreg;
206         return s->tm4[tm].control;
207     case OSNR:
208         return s->snapshot;
209     default:
210     badreg:
211         cpu_abort(cpu_single_env, "pxa2xx_timer_read: Bad offset "
212                         REG_FMT "\n", offset);
213     }
214
215     return 0;
216 }
217
218 static void pxa2xx_timer_write(void *opaque, target_phys_addr_t offset,
219                 uint32_t value)
220 {
221     int i, tm = 0;
222     pxa2xx_timer_info *s = (pxa2xx_timer_info *) opaque;
223
224     offset -= s->base;
225
226     switch (offset) {
227     case OSMR3:  tm ++;
228     case OSMR2:  tm ++;
229     case OSMR1:  tm ++;
230     case OSMR0:
231         s->timer[tm].value = value;
232         pxa2xx_timer_update(s, qemu_get_clock(vm_clock));
233         break;
234     case OSMR11: tm ++;
235     case OSMR10: tm ++;
236     case OSMR9:  tm ++;
237     case OSMR8:  tm ++;
238     case OSMR7:  tm ++;
239     case OSMR6:  tm ++;
240     case OSMR5:  tm ++;
241     case OSMR4:
242         if (!s->tm4)
243             goto badreg;
244         s->tm4[tm].tm.value = value;
245         pxa2xx_timer_update4(s, qemu_get_clock(vm_clock), tm);
246         break;
247     case OSCR:
248         s->oldclock = s->clock;
249         s->lastload = qemu_get_clock(vm_clock);
250         s->clock = value;
251         pxa2xx_timer_update(s, s->lastload);
252         break;
253     case OSCR11: tm ++;
254     case OSCR10: tm ++;
255     case OSCR9:  tm ++;
256     case OSCR8:  tm ++;
257     case OSCR7:  tm ++;
258     case OSCR6:  tm ++;
259     case OSCR5:  tm ++;
260     case OSCR4:
261         if (!s->tm4)
262             goto badreg;
263         s->tm4[tm].oldclock = s->tm4[tm].clock;
264         s->tm4[tm].lastload = qemu_get_clock(vm_clock);
265         s->tm4[tm].clock = value;
266         pxa2xx_timer_update4(s, s->tm4[tm].lastload, tm);
267         break;
268     case OIER:
269         s->irq_enabled = value & 0xfff;
270         break;
271     case OSSR:  /* Status register */
272         s->events &= ~value;
273         for (i = 0; i < 4; i ++, value >>= 1) {
274             if (s->timer[i].level && (value & 1)) {
275                 s->timer[i].level = 0;
276                 qemu_irq_lower(s->timer[i].irq);
277             }
278         }
279         if (s->tm4) {
280             for (i = 0; i < 8; i ++, value >>= 1)
281                 if (s->tm4[i].tm.level && (value & 1))
282                     s->tm4[i].tm.level = 0;
283             if (!(s->events & 0xff0))
284                 qemu_irq_lower(s->tm4->tm.irq);
285         }
286         break;
287     case OWER:  /* XXX: Reset on OSMR3 match? */
288         s->reset3 = value;
289         break;
290     case OMCR7:  tm ++;
291     case OMCR6:  tm ++;
292     case OMCR5:  tm ++;
293     case OMCR4:
294         if (!s->tm4)
295             goto badreg;
296         s->tm4[tm].control = value & 0x0ff;
297         /* XXX Stop if running (shouldn't happen) */
298         if ((value & (1 << 7)) || tm == 0)
299             s->tm4[tm].freq = pxa2xx_timer4_freq[value & 7];
300         else {
301             s->tm4[tm].freq = 0;
302             pxa2xx_timer_update4(s, qemu_get_clock(vm_clock), tm);
303         }
304         break;
305     case OMCR11: tm ++;
306     case OMCR10: tm ++;
307     case OMCR9:  tm ++;
308     case OMCR8:  tm += 4;
309         if (!s->tm4)
310             goto badreg;
311         s->tm4[tm].control = value & 0x3ff;
312         /* XXX Stop if running (shouldn't happen) */
313         if ((value & (1 << 7)) || !(tm & 1))
314             s->tm4[tm].freq =
315                     pxa2xx_timer4_freq[(value & (1 << 8)) ?  0 : (value & 7)];
316         else {
317             s->tm4[tm].freq = 0;
318             pxa2xx_timer_update4(s, qemu_get_clock(vm_clock), tm);
319         }
320         break;
321     default:
322     badreg:
323         cpu_abort(cpu_single_env, "pxa2xx_timer_write: Bad offset "
324                         REG_FMT "\n", offset);
325     }
326 }
327
328 static CPUReadMemoryFunc *pxa2xx_timer_readfn[] = {
329     pxa2xx_timer_read,
330     pxa2xx_timer_read,
331     pxa2xx_timer_read,
332 };
333
334 static CPUWriteMemoryFunc *pxa2xx_timer_writefn[] = {
335     pxa2xx_timer_write,
336     pxa2xx_timer_write,
337     pxa2xx_timer_write,
338 };
339
340 static void pxa2xx_timer_tick(void *opaque)
341 {
342     struct pxa2xx_timer0_s *t = (struct pxa2xx_timer0_s *) opaque;
343     pxa2xx_timer_info *i = (pxa2xx_timer_info *) t->info;
344
345     if (i->irq_enabled & (1 << t->num)) {
346         t->level = 1;
347         i->events |= 1 << t->num;
348         qemu_irq_raise(t->irq);
349     }
350
351     if (t->num == 3)
352         if (i->reset3 & 1) {
353             i->reset3 = 0;
354             qemu_system_reset_request();
355         }
356 }
357
358 static void pxa2xx_timer_tick4(void *opaque)
359 {
360     struct pxa2xx_timer4_s *t = (struct pxa2xx_timer4_s *) opaque;
361     pxa2xx_timer_info *i = (pxa2xx_timer_info *) t->tm.info;
362
363     pxa2xx_timer_tick(&t->tm);
364     if (t->control & (1 << 3))
365         t->clock = 0;
366     if (t->control & (1 << 6))
367         pxa2xx_timer_update4(i, qemu_get_clock(vm_clock), t->tm.num - 4);
368 }
369
370 static void pxa2xx_timer_save(QEMUFile *f, void *opaque)
371 {
372     pxa2xx_timer_info *s = (pxa2xx_timer_info *) opaque;
373     int i;
374
375     qemu_put_be32s(f, (uint32_t *) &s->clock);
376     qemu_put_be32s(f, (uint32_t *) &s->oldclock);
377     qemu_put_be64s(f, &s->lastload);
378
379     for (i = 0; i < 4; i ++) {
380         qemu_put_be32s(f, &s->timer[i].value);
381         qemu_put_be32(f, s->timer[i].level);
382     }
383     if (s->tm4)
384         for (i = 0; i < 8; i ++) {
385             qemu_put_be32s(f, &s->tm4[i].tm.value);
386             qemu_put_be32(f, s->tm4[i].tm.level);
387             qemu_put_sbe32s(f, &s->tm4[i].oldclock);
388             qemu_put_sbe32s(f, &s->tm4[i].clock);
389             qemu_put_be64s(f, &s->tm4[i].lastload);
390             qemu_put_be32s(f, &s->tm4[i].freq);
391             qemu_put_be32s(f, &s->tm4[i].control);
392         }
393
394     qemu_put_be32s(f, &s->events);
395     qemu_put_be32s(f, &s->irq_enabled);
396     qemu_put_be32s(f, &s->reset3);
397     qemu_put_be32s(f, &s->snapshot);
398 }
399
400 static int pxa2xx_timer_load(QEMUFile *f, void *opaque, int version_id)
401 {
402     pxa2xx_timer_info *s = (pxa2xx_timer_info *) opaque;
403     int64_t now;
404     int i;
405
406     qemu_get_be32s(f, (uint32_t *) &s->clock);
407     qemu_get_be32s(f, (uint32_t *) &s->oldclock);
408     qemu_get_be64s(f, &s->lastload);
409
410     now = qemu_get_clock(vm_clock);
411     for (i = 0; i < 4; i ++) {
412         qemu_get_be32s(f, &s->timer[i].value);
413         s->timer[i].level = qemu_get_be32(f);
414     }
415     pxa2xx_timer_update(s, now);
416
417     if (s->tm4)
418         for (i = 0; i < 8; i ++) {
419             qemu_get_be32s(f, &s->tm4[i].tm.value);
420             s->tm4[i].tm.level = qemu_get_be32(f);
421             qemu_get_sbe32s(f, &s->tm4[i].oldclock);
422             qemu_get_sbe32s(f, &s->tm4[i].clock);
423             qemu_get_be64s(f, &s->tm4[i].lastload);
424             qemu_get_be32s(f, &s->tm4[i].freq);
425             qemu_get_be32s(f, &s->tm4[i].control);
426             pxa2xx_timer_update4(s, now, i);
427         }
428
429     qemu_get_be32s(f, &s->events);
430     qemu_get_be32s(f, &s->irq_enabled);
431     qemu_get_be32s(f, &s->reset3);
432     qemu_get_be32s(f, &s->snapshot);
433
434     return 0;
435 }
436
437 static pxa2xx_timer_info *pxa2xx_timer_init(target_phys_addr_t base,
438                 qemu_irq *irqs)
439 {
440     int i;
441     int iomemtype;
442     pxa2xx_timer_info *s;
443
444     s = (pxa2xx_timer_info *) qemu_mallocz(sizeof(pxa2xx_timer_info));
445     s->base = base;
446     s->irq_enabled = 0;
447     s->oldclock = 0;
448     s->clock = 0;
449     s->lastload = qemu_get_clock(vm_clock);
450     s->reset3 = 0;
451
452     for (i = 0; i < 4; i ++) {
453         s->timer[i].value = 0;
454         s->timer[i].irq = irqs[i];
455         s->timer[i].info = s;
456         s->timer[i].num = i;
457         s->timer[i].level = 0;
458         s->timer[i].qtimer = qemu_new_timer(vm_clock,
459                         pxa2xx_timer_tick, &s->timer[i]);
460     }
461
462     iomemtype = cpu_register_io_memory(0, pxa2xx_timer_readfn,
463                     pxa2xx_timer_writefn, s);
464     cpu_register_physical_memory(base, 0x00001000, iomemtype);
465
466     register_savevm("pxa2xx_timer", 0, 0,
467                     pxa2xx_timer_save, pxa2xx_timer_load, s);
468
469     return s;
470 }
471
472 void pxa25x_timer_init(target_phys_addr_t base, qemu_irq *irqs)
473 {
474     pxa2xx_timer_info *s = pxa2xx_timer_init(base, irqs);
475     s->freq = PXA25X_FREQ;
476     s->tm4 = 0;
477 }
478
479 void pxa27x_timer_init(target_phys_addr_t base,
480                 qemu_irq *irqs, qemu_irq irq4)
481 {
482     pxa2xx_timer_info *s = pxa2xx_timer_init(base, irqs);
483     int i;
484     s->freq = PXA27X_FREQ;
485     s->tm4 = (struct pxa2xx_timer4_s *) qemu_mallocz(8 *
486                     sizeof(struct pxa2xx_timer4_s));
487     for (i = 0; i < 8; i ++) {
488         s->tm4[i].tm.value = 0;
489         s->tm4[i].tm.irq = irq4;
490         s->tm4[i].tm.info = s;
491         s->tm4[i].tm.num = i + 4;
492         s->tm4[i].tm.level = 0;
493         s->tm4[i].freq = 0;
494         s->tm4[i].control = 0x0;
495         s->tm4[i].tm.qtimer = qemu_new_timer(vm_clock,
496                         pxa2xx_timer_tick4, &s->tm4[i]);
497     }
498 }