Statistics
| Branch: | Revision:

root / hw / pxa2xx_timer.c @ aa941b94

History | View | Annotate | Download (13.3 kB)

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
    target_phys_addr_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
    uint32_t snapshot;
89
} pxa2xx_timer_info;
90

    
91
static void pxa2xx_timer_update(void *opaque, uint64_t now_qemu)
92
{
93
    pxa2xx_timer_info *s = (pxa2xx_timer_info *) opaque;
94
    int i;
95
    uint32_t now_vm;
96
    uint64_t new_qemu;
97

    
98
    now_vm = s->clock +
99
            muldiv64(now_qemu - s->lastload, s->freq, ticks_per_sec);
100

    
101
    for (i = 0; i < 4; i ++) {
102
        new_qemu = now_qemu + muldiv64((uint32_t) (s->timer[i].value - now_vm),
103
                        ticks_per_sec, s->freq);
104
        qemu_mod_timer(s->timer[i].qtimer, new_qemu);
105
    }
106
}
107

    
108
static void pxa2xx_timer_update4(void *opaque, uint64_t now_qemu, int n)
109
{
110
    pxa2xx_timer_info *s = (pxa2xx_timer_info *) opaque;
111
    uint32_t now_vm;
112
    uint64_t new_qemu;
113
    static const int counters[8] = { 0, 0, 0, 0, 4, 4, 6, 6 };
114
    int counter;
115

    
116
    if (s->tm4[n].control & (1 << 7))
117
        counter = n;
118
    else
119
        counter = counters[n];
120

    
121
    if (!s->tm4[counter].freq) {
122
        qemu_del_timer(s->tm4[n].tm.qtimer);
123
        return;
124
    }
125

    
126
    now_vm = s->tm4[counter].clock + muldiv64(now_qemu -
127
                    s->tm4[counter].lastload,
128
                    s->tm4[counter].freq, ticks_per_sec);
129

    
130
    new_qemu = now_qemu + muldiv64((uint32_t) (s->tm4[n].tm.value - now_vm),
131
                    ticks_per_sec, s->tm4[counter].freq);
132
    qemu_mod_timer(s->tm4[n].tm.qtimer, new_qemu);
133
}
134

    
135
static uint32_t pxa2xx_timer_read(void *opaque, target_phys_addr_t offset)
136
{
137
    pxa2xx_timer_info *s = (pxa2xx_timer_info *) opaque;
138
    int tm = 0;
139

    
140
    offset -= s->base;
141

    
142
    switch (offset) {
143
    case OSMR3:  tm ++;
144
    case OSMR2:  tm ++;
145
    case OSMR1:  tm ++;
146
    case OSMR0:
147
        return s->timer[tm].value;
148
    case OSMR11: tm ++;
149
    case OSMR10: tm ++;
150
    case OSMR9:  tm ++;
151
    case OSMR8:  tm ++;
152
    case OSMR7:  tm ++;
153
    case OSMR6:  tm ++;
154
    case OSMR5:  tm ++;
155
    case OSMR4:
156
        if (!s->tm4)
157
            goto badreg;
158
        return s->tm4[tm].tm.value;
159
    case OSCR:
160
        return s->clock + muldiv64(qemu_get_clock(vm_clock) -
161
                        s->lastload, s->freq, ticks_per_sec);
162
    case OSCR11: tm ++;
163
    case OSCR10: tm ++;
164
    case OSCR9:  tm ++;
165
    case OSCR8:  tm ++;
166
    case OSCR7:  tm ++;
167
    case OSCR6:  tm ++;
168
    case OSCR5:  tm ++;
169
    case OSCR4:
170
        if (!s->tm4)
171
            goto badreg;
172

    
173
        if ((tm == 9 - 4 || tm == 11 - 4) && (s->tm4[tm].control & (1 << 9))) {
174
            if (s->tm4[tm - 1].freq)
175
                s->snapshot = s->tm4[tm - 1].clock + muldiv64(
176
                                qemu_get_clock(vm_clock) -
177
                                s->tm4[tm - 1].lastload,
178
                                s->tm4[tm - 1].freq, ticks_per_sec);
179
            else
180
                s->snapshot = s->tm4[tm - 1].clock;
181
        }
182

    
183
        if (!s->tm4[tm].freq)
184
            return s->tm4[tm].clock;
185
        return s->tm4[tm].clock + muldiv64(qemu_get_clock(vm_clock) -
186
                        s->tm4[tm].lastload, s->tm4[tm].freq, ticks_per_sec);
187
    case OIER:
188
        return s->irq_enabled;
189
    case OSSR:        /* Status register */
190
        return s->events;
191
    case OWER:
192
        return s->reset3;
193
    case OMCR11: tm ++;
194
    case OMCR10: tm ++;
195
    case OMCR9:  tm ++;
196
    case OMCR8:  tm ++;
197
    case OMCR7:  tm ++;
198
    case OMCR6:  tm ++;
199
    case OMCR5:  tm ++;
200
    case OMCR4:
201
        if (!s->tm4)
202
            goto badreg;
203
        return s->tm4[tm].control;
204
    case OSNR:
205
        return s->snapshot;
206
    default:
207
    badreg:
208
        cpu_abort(cpu_single_env, "pxa2xx_timer_read: Bad offset "
209
                        REG_FMT "\n", offset);
210
    }
211

    
212
    return 0;
213
}
214

    
215
static void pxa2xx_timer_write(void *opaque, target_phys_addr_t offset,
216
                uint32_t value)
217
{
218
    int i, tm = 0;
219
    pxa2xx_timer_info *s = (pxa2xx_timer_info *) opaque;
220

    
221
    offset -= s->base;
222

    
223
    switch (offset) {
224
    case OSMR3:  tm ++;
225
    case OSMR2:  tm ++;
226
    case OSMR1:  tm ++;
227
    case OSMR0:
228
        s->timer[tm].value = value;
229
        pxa2xx_timer_update(s, qemu_get_clock(vm_clock));
230
        break;
231
    case OSMR11: tm ++;
232
    case OSMR10: tm ++;
233
    case OSMR9:  tm ++;
234
    case OSMR8:  tm ++;
235
    case OSMR7:  tm ++;
236
    case OSMR6:  tm ++;
237
    case OSMR5:  tm ++;
238
    case OSMR4:
239
        if (!s->tm4)
240
            goto badreg;
241
        s->tm4[tm].tm.value = value;
242
        pxa2xx_timer_update4(s, qemu_get_clock(vm_clock), tm);
243
        break;
244
    case OSCR:
245
        s->oldclock = s->clock;
246
        s->lastload = qemu_get_clock(vm_clock);
247
        s->clock = value;
248
        pxa2xx_timer_update(s, s->lastload);
249
        break;
250
    case OSCR11: tm ++;
251
    case OSCR10: tm ++;
252
    case OSCR9:  tm ++;
253
    case OSCR8:  tm ++;
254
    case OSCR7:  tm ++;
255
    case OSCR6:  tm ++;
256
    case OSCR5:  tm ++;
257
    case OSCR4:
258
        if (!s->tm4)
259
            goto badreg;
260
        s->tm4[tm].oldclock = s->tm4[tm].clock;
261
        s->tm4[tm].lastload = qemu_get_clock(vm_clock);
262
        s->tm4[tm].clock = value;
263
        pxa2xx_timer_update4(s, s->tm4[tm].lastload, tm);
264
        break;
265
    case OIER:
266
        s->irq_enabled = value & 0xfff;
267
        break;
268
    case OSSR:        /* Status register */
269
        s->events &= ~value;
270
        for (i = 0; i < 4; i ++, value >>= 1) {
271
            if (s->timer[i].level && (value & 1)) {
272
                s->timer[i].level = 0;
273
                qemu_irq_lower(s->timer[i].irq);
274
            }
275
        }
276
        if (s->tm4) {
277
            for (i = 0; i < 8; i ++, value >>= 1)
278
                if (s->tm4[i].tm.level && (value & 1))
279
                    s->tm4[i].tm.level = 0;
280
            if (!(s->events & 0xff0))
281
                qemu_irq_lower(s->tm4->tm.irq);
282
        }
283
        break;
284
    case OWER:        /* XXX: Reset on OSMR3 match? */
285
        s->reset3 = value;
286
        break;
287
    case OMCR7:  tm ++;
288
    case OMCR6:  tm ++;
289
    case OMCR5:  tm ++;
290
    case OMCR4:
291
        if (!s->tm4)
292
            goto badreg;
293
        s->tm4[tm].control = value & 0x0ff;
294
        /* XXX Stop if running (shouldn't happen) */
295
        if ((value & (1 << 7)) || tm == 0)
296
            s->tm4[tm].freq = pxa2xx_timer4_freq[value & 7];
297
        else {
298
            s->tm4[tm].freq = 0;
299
            pxa2xx_timer_update4(s, qemu_get_clock(vm_clock), tm);
300
        }
301
        break;
302
    case OMCR11: tm ++;
303
    case OMCR10: tm ++;
304
    case OMCR9:  tm ++;
305
    case OMCR8:  tm += 4;
306
        if (!s->tm4)
307
            goto badreg;
308
        s->tm4[tm].control = value & 0x3ff;
309
        /* XXX Stop if running (shouldn't happen) */
310
        if ((value & (1 << 7)) || !(tm & 1))
311
            s->tm4[tm].freq =
312
                    pxa2xx_timer4_freq[(value & (1 << 8)) ?  0 : (value & 7)];
313
        else {
314
            s->tm4[tm].freq = 0;
315
            pxa2xx_timer_update4(s, qemu_get_clock(vm_clock), tm);
316
        }
317
        break;
318
    default:
319
    badreg:
320
        cpu_abort(cpu_single_env, "pxa2xx_timer_write: Bad offset "
321
                        REG_FMT "\n", offset);
322
    }
323
}
324

    
325
static CPUReadMemoryFunc *pxa2xx_timer_readfn[] = {
326
    pxa2xx_timer_read,
327
    pxa2xx_timer_read,
328
    pxa2xx_timer_read,
329
};
330

    
331
static CPUWriteMemoryFunc *pxa2xx_timer_writefn[] = {
332
    pxa2xx_timer_write,
333
    pxa2xx_timer_write,
334
    pxa2xx_timer_write,
335
};
336

    
337
static void pxa2xx_timer_tick(void *opaque)
338
{
339
    struct pxa2xx_timer0_s *t = (struct pxa2xx_timer0_s *) opaque;
340
    pxa2xx_timer_info *i = (pxa2xx_timer_info *) t->info;
341

    
342
    if (i->irq_enabled & (1 << t->num)) {
343
        t->level = 1;
344
        i->events |= 1 << t->num;
345
        qemu_irq_raise(t->irq);
346
    }
347

    
348
    if (t->num == 3)
349
        if (i->reset3 & 1) {
350
            i->reset3 = 0;
351
            qemu_system_reset_request();
352
        }
353
}
354

    
355
static void pxa2xx_timer_tick4(void *opaque)
356
{
357
    struct pxa2xx_timer4_s *t = (struct pxa2xx_timer4_s *) opaque;
358
    pxa2xx_timer_info *i = (pxa2xx_timer_info *) t->tm.info;
359

    
360
    pxa2xx_timer_tick(&t->tm);
361
    if (t->control & (1 << 3))
362
        t->clock = 0;
363
    if (t->control & (1 << 6))
364
        pxa2xx_timer_update4(i, qemu_get_clock(vm_clock), t->tm.num - 4);
365
}
366

    
367
static void pxa2xx_timer_save(QEMUFile *f, void *opaque)
368
{
369
    pxa2xx_timer_info *s = (pxa2xx_timer_info *) opaque;
370
    int i;
371

    
372
    qemu_put_be32s(f, &s->clock);
373
    qemu_put_be32s(f, &s->oldclock);
374
    qemu_put_be64s(f, &s->lastload);
375

    
376
    for (i = 0; i < 4; i ++) {
377
        qemu_put_be32s(f, &s->timer[i].value);
378
        qemu_put_be32(f, s->timer[i].level);
379
    }
380
    if (s->tm4)
381
        for (i = 0; i < 8; i ++) {
382
            qemu_put_be32s(f, &s->tm4[i].tm.value);
383
            qemu_put_be32(f, s->tm4[i].tm.level);
384
            qemu_put_be32s(f, &s->tm4[i].oldclock);
385
            qemu_put_be32s(f, &s->tm4[i].clock);
386
            qemu_put_be64s(f, &s->tm4[i].lastload);
387
            qemu_put_be32s(f, &s->tm4[i].freq);
388
            qemu_put_be32s(f, &s->tm4[i].control);
389
        }
390

    
391
    qemu_put_be32s(f, &s->events);
392
    qemu_put_be32s(f, &s->irq_enabled);
393
    qemu_put_be32s(f, &s->reset3);
394
    qemu_put_be32s(f, &s->snapshot);
395
}
396

    
397
static int pxa2xx_timer_load(QEMUFile *f, void *opaque, int version_id)
398
{
399
    pxa2xx_timer_info *s = (pxa2xx_timer_info *) opaque;
400
    int64_t now;
401
    int i;
402

    
403
    qemu_get_be32s(f, &s->clock);
404
    qemu_get_be32s(f, &s->oldclock);
405
    qemu_get_be64s(f, &s->lastload);
406

    
407
    now = qemu_get_clock(vm_clock);
408
    for (i = 0; i < 4; i ++) {
409
        qemu_get_be32s(f, &s->timer[i].value);
410
        s->timer[i].level = qemu_get_be32(f);
411
    }
412
    pxa2xx_timer_update(s, now);
413

    
414
    if (s->tm4)
415
        for (i = 0; i < 8; i ++) {
416
            qemu_get_be32s(f, &s->tm4[i].tm.value);
417
            s->tm4[i].tm.level = qemu_get_be32(f);
418
            qemu_get_be32s(f, &s->tm4[i].oldclock);
419
            qemu_get_be32s(f, &s->tm4[i].clock);
420
            qemu_get_be64s(f, &s->tm4[i].lastload);
421
            qemu_get_be32s(f, &s->tm4[i].freq);
422
            qemu_get_be32s(f, &s->tm4[i].control);
423
            pxa2xx_timer_update4(s, now, i);
424
        }
425

    
426
    qemu_get_be32s(f, &s->events);
427
    qemu_get_be32s(f, &s->irq_enabled);
428
    qemu_get_be32s(f, &s->reset3);
429
    qemu_get_be32s(f, &s->snapshot);
430

    
431
    return 0;
432
}
433

    
434
static pxa2xx_timer_info *pxa2xx_timer_init(target_phys_addr_t base,
435
                qemu_irq *irqs)
436
{
437
    int i;
438
    int iomemtype;
439
    pxa2xx_timer_info *s;
440

    
441
    s = (pxa2xx_timer_info *) qemu_mallocz(sizeof(pxa2xx_timer_info));
442
    s->base = base;
443
    s->irq_enabled = 0;
444
    s->oldclock = 0;
445
    s->clock = 0;
446
    s->lastload = qemu_get_clock(vm_clock);
447
    s->reset3 = 0;
448

    
449
    for (i = 0; i < 4; i ++) {
450
        s->timer[i].value = 0;
451
        s->timer[i].irq = irqs[i];
452
        s->timer[i].info = s;
453
        s->timer[i].num = i;
454
        s->timer[i].level = 0;
455
        s->timer[i].qtimer = qemu_new_timer(vm_clock,
456
                        pxa2xx_timer_tick, &s->timer[i]);
457
    }
458

    
459
    iomemtype = cpu_register_io_memory(0, pxa2xx_timer_readfn,
460
                    pxa2xx_timer_writefn, s);
461
    cpu_register_physical_memory(base, 0x00000fff, iomemtype);
462

    
463
    register_savevm("pxa2xx_timer", 0, 0,
464
                    pxa2xx_timer_save, pxa2xx_timer_load, s);
465

    
466
    return s;
467
}
468

    
469
void pxa25x_timer_init(target_phys_addr_t base, qemu_irq *irqs)
470
{
471
    pxa2xx_timer_info *s = pxa2xx_timer_init(base, irqs);
472
    s->freq = PXA25X_FREQ;
473
    s->tm4 = 0;
474
}
475

    
476
void pxa27x_timer_init(target_phys_addr_t base,
477
                qemu_irq *irqs, qemu_irq irq4)
478
{
479
    pxa2xx_timer_info *s = pxa2xx_timer_init(base, irqs);
480
    int i;
481
    s->freq = PXA27X_FREQ;
482
    s->tm4 = (struct pxa2xx_timer4_s *) qemu_mallocz(8 *
483
                    sizeof(struct pxa2xx_timer4_s));
484
    for (i = 0; i < 8; i ++) {
485
        s->tm4[i].tm.value = 0;
486
        s->tm4[i].tm.irq = irq4;
487
        s->tm4[i].tm.info = s;
488
        s->tm4[i].tm.num = i + 4;
489
        s->tm4[i].tm.level = 0;
490
        s->tm4[i].freq = 0;
491
        s->tm4[i].control = 0x0;
492
        s->tm4[i].tm.qtimer = qemu_new_timer(vm_clock,
493
                        pxa2xx_timer_tick4, &s->tm4[i]);
494
    }
495
}