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