Statistics
| Branch: | Revision:

root / hw / pxa2xx_timer.c @ d353eb43

History | View | Annotate | Download (13.2 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 "hw.h"
11
#include "qemu-timer.h"
12
#include "sysemu.h"
13
#include "qdev.h"
14
#include "pxa.h"
15

    
16
#define OSMR0        0x00
17
#define OSMR1        0x04
18
#define OSMR2        0x08
19
#define OSMR3        0x0c
20
#define OSMR4        0x80
21
#define OSMR5        0x84
22
#define OSMR6        0x88
23
#define OSMR7        0x8c
24
#define OSMR8        0x90
25
#define OSMR9        0x94
26
#define OSMR10        0x98
27
#define OSMR11        0x9c
28
#define OSCR        0x10        /* OS Timer Count */
29
#define OSCR4        0x40
30
#define OSCR5        0x44
31
#define OSCR6        0x48
32
#define OSCR7        0x4c
33
#define OSCR8        0x50
34
#define OSCR9        0x54
35
#define OSCR10        0x58
36
#define OSCR11        0x5c
37
#define OSSR        0x14        /* Timer status register */
38
#define OWER        0x18
39
#define OIER        0x1c        /* Interrupt enable register  3-0 to E3-E0 */
40
#define OMCR4        0xc0        /* OS Match Control registers */
41
#define OMCR5        0xc4
42
#define OMCR6        0xc8
43
#define OMCR7        0xcc
44
#define OMCR8        0xd0
45
#define OMCR9        0xd4
46
#define OMCR10        0xd8
47
#define OMCR11        0xdc
48
#define OSNR        0x20
49

    
50
#define PXA25X_FREQ        3686400        /* 3.6864 MHz */
51
#define PXA27X_FREQ        3250000        /* 3.25 MHz */
52

    
53
static int pxa2xx_timer4_freq[8] = {
54
    [0] = 0,
55
    [1] = 32768,
56
    [2] = 1000,
57
    [3] = 1,
58
    [4] = 1000000,
59
    /* [5] is the "Externally supplied clock".  Assign if necessary.  */
60
    [5 ... 7] = 0,
61
};
62

    
63
typedef struct {
64
    uint32_t value;
65
    int level;
66
    qemu_irq irq;
67
    QEMUTimer *qtimer;
68
    int num;
69
    void *info;
70
} PXA2xxTimer0;
71

    
72
typedef struct {
73
    PXA2xxTimer0 tm;
74
    int32_t oldclock;
75
    int32_t clock;
76
    uint64_t lastload;
77
    uint32_t freq;
78
    uint32_t control;
79
} PXA2xxTimer4;
80

    
81
typedef struct {
82
    int32_t clock;
83
    int32_t oldclock;
84
    uint64_t lastload;
85
    uint32_t freq;
86
    PXA2xxTimer0 timer[4];
87
    PXA2xxTimer4 *tm4;
88
    uint32_t events;
89
    uint32_t irq_enabled;
90
    uint32_t reset3;
91
    uint32_t snapshot;
92
} PXA2xxTimerInfo;
93

    
94
static void pxa2xx_timer_update(void *opaque, uint64_t now_qemu)
95
{
96
    PXA2xxTimerInfo *s = (PXA2xxTimerInfo *) 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, get_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
                        get_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
    PXA2xxTimerInfo *s = (PXA2xxTimerInfo *) 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, get_ticks_per_sec());
132

    
133
    new_qemu = now_qemu + muldiv64((uint32_t) (s->tm4[n].tm.value - now_vm),
134
                    get_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
    PXA2xxTimerInfo *s = (PXA2xxTimerInfo *) opaque;
141
    int tm = 0;
142

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

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

    
184
        if (!s->tm4[tm].freq)
185
            return s->tm4[tm].clock;
186
        return s->tm4[tm].clock + muldiv64(qemu_get_clock(vm_clock) -
187
                        s->tm4[tm].lastload, s->tm4[tm].freq, get_ticks_per_sec());
188
    case OIER:
189
        return s->irq_enabled;
190
    case OSSR:        /* Status register */
191
        return s->events;
192
    case OWER:
193
        return s->reset3;
194
    case OMCR11: tm ++;
195
    case OMCR10: tm ++;
196
    case OMCR9:  tm ++;
197
    case OMCR8:  tm ++;
198
    case OMCR7:  tm ++;
199
    case OMCR6:  tm ++;
200
    case OMCR5:  tm ++;
201
    case OMCR4:
202
        if (!s->tm4)
203
            goto badreg;
204
        return s->tm4[tm].control;
205
    case OSNR:
206
        return s->snapshot;
207
    default:
208
    badreg:
209
        hw_error("pxa2xx_timer_read: Bad offset " 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
    PXA2xxTimerInfo *s = (PXA2xxTimerInfo *) opaque;
220

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

    
322
static CPUReadMemoryFunc * const pxa2xx_timer_readfn[] = {
323
    pxa2xx_timer_read,
324
    pxa2xx_timer_read,
325
    pxa2xx_timer_read,
326
};
327

    
328
static CPUWriteMemoryFunc * const pxa2xx_timer_writefn[] = {
329
    pxa2xx_timer_write,
330
    pxa2xx_timer_write,
331
    pxa2xx_timer_write,
332
};
333

    
334
static void pxa2xx_timer_tick(void *opaque)
335
{
336
    PXA2xxTimer0 *t = (PXA2xxTimer0 *) opaque;
337
    PXA2xxTimerInfo *i = (PXA2xxTimerInfo *) t->info;
338

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

    
345
    if (t->num == 3)
346
        if (i->reset3 & 1) {
347
            i->reset3 = 0;
348
            qemu_system_reset_request();
349
        }
350
}
351

    
352
static void pxa2xx_timer_tick4(void *opaque)
353
{
354
    PXA2xxTimer4 *t = (PXA2xxTimer4 *) opaque;
355
    PXA2xxTimerInfo *i = (PXA2xxTimerInfo *) t->tm.info;
356

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

    
364
static void pxa2xx_timer_save(QEMUFile *f, void *opaque)
365
{
366
    PXA2xxTimerInfo *s = (PXA2xxTimerInfo *) opaque;
367
    int i;
368

    
369
    qemu_put_be32s(f, (uint32_t *) &s->clock);
370
    qemu_put_be32s(f, (uint32_t *) &s->oldclock);
371
    qemu_put_be64s(f, &s->lastload);
372

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

    
388
    qemu_put_be32s(f, &s->events);
389
    qemu_put_be32s(f, &s->irq_enabled);
390
    qemu_put_be32s(f, &s->reset3);
391
    qemu_put_be32s(f, &s->snapshot);
392
}
393

    
394
static int pxa2xx_timer_load(QEMUFile *f, void *opaque, int version_id)
395
{
396
    PXA2xxTimerInfo *s = (PXA2xxTimerInfo *) opaque;
397
    int64_t now;
398
    int i;
399

    
400
    qemu_get_be32s(f, (uint32_t *) &s->clock);
401
    qemu_get_be32s(f, (uint32_t *) &s->oldclock);
402
    qemu_get_be64s(f, &s->lastload);
403

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

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

    
423
    qemu_get_be32s(f, &s->events);
424
    qemu_get_be32s(f, &s->irq_enabled);
425
    qemu_get_be32s(f, &s->reset3);
426
    qemu_get_be32s(f, &s->snapshot);
427

    
428
    return 0;
429
}
430

    
431
static PXA2xxTimerInfo *pxa2xx_timer_init(target_phys_addr_t base,
432
                DeviceState *pic)
433
{
434
    int i;
435
    int iomemtype;
436
    PXA2xxTimerInfo *s;
437

    
438
    s = (PXA2xxTimerInfo *) qemu_mallocz(sizeof(PXA2xxTimerInfo));
439
    s->irq_enabled = 0;
440
    s->oldclock = 0;
441
    s->clock = 0;
442
    s->lastload = qemu_get_clock(vm_clock);
443
    s->reset3 = 0;
444

    
445
    for (i = 0; i < 4; i ++) {
446
        s->timer[i].value = 0;
447
        s->timer[i].irq = qdev_get_gpio_in(pic, PXA2XX_PIC_OST_0 + i);
448
        s->timer[i].info = s;
449
        s->timer[i].num = i;
450
        s->timer[i].level = 0;
451
        s->timer[i].qtimer = qemu_new_timer(vm_clock,
452
                        pxa2xx_timer_tick, &s->timer[i]);
453
    }
454

    
455
    iomemtype = cpu_register_io_memory(pxa2xx_timer_readfn,
456
                    pxa2xx_timer_writefn, s, DEVICE_NATIVE_ENDIAN);
457
    cpu_register_physical_memory(base, 0x00001000, iomemtype);
458

    
459
    register_savevm(NULL, "pxa2xx_timer", 0, 0,
460
                    pxa2xx_timer_save, pxa2xx_timer_load, s);
461

    
462
    return s;
463
}
464

    
465
void pxa25x_timer_init(target_phys_addr_t base, DeviceState *pic)
466
{
467
    PXA2xxTimerInfo *s = pxa2xx_timer_init(base, pic);
468
    s->freq = PXA25X_FREQ;
469
    s->tm4 = NULL;
470
}
471

    
472
void pxa27x_timer_init(target_phys_addr_t base, DeviceState *pic)
473
{
474
    PXA2xxTimerInfo *s = pxa2xx_timer_init(base, pic);
475
    int i;
476
    s->freq = PXA27X_FREQ;
477
    s->tm4 = (PXA2xxTimer4 *) qemu_mallocz(8 *
478
                    sizeof(PXA2xxTimer4));
479
    for (i = 0; i < 8; i ++) {
480
        s->tm4[i].tm.value = 0;
481
        s->tm4[i].tm.irq = qdev_get_gpio_in(pic, PXA27X_PIC_OST_4_11);
482
        s->tm4[i].tm.info = s;
483
        s->tm4[i].tm.num = i + 4;
484
        s->tm4[i].tm.level = 0;
485
        s->tm4[i].freq = 0;
486
        s->tm4[i].control = 0x0;
487
        s->tm4[i].tm.qtimer = qemu_new_timer(vm_clock,
488
                        pxa2xx_timer_tick4, &s->tm4[i]);
489
    }
490
}