~ubuntu-branches/ubuntu/trusty/qemu/trusty

« back to all changes in this revision

Viewing changes to hw/timer/imx_gpt.c

  • Committer: Package Import Robot
  • Author(s): Serge Hallyn
  • Date: 2013-10-22 22:47:07 UTC
  • mfrom: (1.8.3) (10.1.42 sid)
  • Revision ID: package-import@ubuntu.com-20131022224707-1lya34fw3k3f24tv
Tags: 1.6.0+dfsg-2ubuntu1
* Merge 1.6.0~rc0+dfsg-2exp from debian experimental.  Remaining changes:
  - debian/control
    * update maintainer
    * remove libiscsi, usb-redir, vde, vnc-jpeg, and libssh2-1-dev
      from build-deps
    * enable rbd
    * add qemu-system and qemu-common B/R to qemu-keymaps
    * add D:udev, R:qemu, R:qemu-common and B:qemu-common to
      qemu-system-common
    * qemu-system-arm, qemu-system-ppc, qemu-system-sparc:
      - add qemu-kvm to Provides
      - add qemu-common, qemu-kvm, kvm to B/R
      - remove openbios-sparc from qemu-system-sparc D
      - drop openbios-ppc and openhackware Depends to Suggests (for now)
    * qemu-system-x86:
      - add qemu-common to Breaks/Replaces.
      - add cpu-checker to Recommends.
    * qemu-user: add B/R:qemu-kvm
    * qemu-kvm:
      - add armhf armel powerpc sparc to Architecture
      - C/R/P: qemu-kvm-spice
    * add qemu-common package
    * drop qemu-slof which is not packaged in ubuntu
  - add qemu-system-common.links for tap ifup/down scripts and OVMF link.
  - qemu-system-x86.links:
    * remove pxe rom links which are in kvm-ipxe
    * add symlink for kvm.1 manpage
  - debian/rules
    * add kvm-spice symlink to qemu-kvm
    * call dh_installmodules for qemu-system-x86
    * update dh_installinit to install upstart script
    * run dh_installman (Closes: #709241) (cherrypicked from 1.5.0+dfsg-2)
  - Add qemu-utils.links for kvm-* symlinks.
  - Add qemu-system-x86.qemu-kvm.upstart and .default
  - Add qemu-system-x86.modprobe to set nesting=1
  - Add qemu-system-common.preinst to add kvm group
  - qemu-system-common.postinst: remove bad group acl if there, then have
    udev relabel /dev/kvm.
  - New linaro patches from qemu-linaro rebasing branch
  - Dropped patches:
    * xen-simplify-xen_enabled.patch
    * sparc-linux-user-fix-missing-symbols-in-.rel-.rela.plt-sections.patch
    * main_loop-do-not-set-nonblocking-if-xen_enabled.patch
    * xen_machine_pv-do-not-create-a-dummy-CPU-in-machine-.patch
    * virtio-rng-fix-crash
  - Kept patches:
    * expose_vms_qemu64cpu.patch - updated
    * linaro arm patches from qemu-linaro rebasing branch
  - New patches:
    * fix-pci-add: change CONFIG variable in ifdef to make sure that
      pci_add is defined.
* Add linaro patches
* Add experimental mach-virt patches for arm virtualization.
* qemu-system-common.install: add debian/tmp/usr/lib to install the
  qemu-bridge-helper

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/*
 
2
 * IMX GPT Timer
 
3
 *
 
4
 * Copyright (c) 2008 OK Labs
 
5
 * Copyright (c) 2011 NICTA Pty Ltd
 
6
 * Originally written by Hans Jiang
 
7
 * Updated by Peter Chubb
 
8
 * Updated by Jean-Christophe Dubois
 
9
 *
 
10
 * This code is licensed under GPL version 2 or later.  See
 
11
 * the COPYING file in the top-level directory.
 
12
 *
 
13
 */
 
14
 
 
15
#include "hw/hw.h"
 
16
#include "qemu/bitops.h"
 
17
#include "qemu/timer.h"
 
18
#include "hw/ptimer.h"
 
19
#include "hw/sysbus.h"
 
20
#include "hw/arm/imx.h"
 
21
 
 
22
#define TYPE_IMX_GPT "imx.gpt"
 
23
 
 
24
/*
 
25
 * Define to 1 for debug messages
 
26
 */
 
27
#define DEBUG_TIMER 0
 
28
#if DEBUG_TIMER
 
29
 
 
30
static char const *imx_gpt_reg_name(uint32_t reg)
 
31
{
 
32
    switch (reg) {
 
33
    case 0:
 
34
        return "CR";
 
35
    case 1:
 
36
        return "PR";
 
37
    case 2:
 
38
        return "SR";
 
39
    case 3:
 
40
        return "IR";
 
41
    case 4:
 
42
        return "OCR1";
 
43
    case 5:
 
44
        return "OCR2";
 
45
    case 6:
 
46
        return "OCR3";
 
47
    case 7:
 
48
        return "ICR1";
 
49
    case 8:
 
50
        return "ICR2";
 
51
    case 9:
 
52
        return "CNT";
 
53
    default:
 
54
        return "[?]";
 
55
    }
 
56
}
 
57
 
 
58
#  define DPRINTF(fmt, args...) \
 
59
          do { printf("%s: " fmt , __func__, ##args); } while (0)
 
60
#else
 
61
#  define DPRINTF(fmt, args...) do {} while (0)
 
62
#endif
 
63
 
 
64
/*
 
65
 * Define to 1 for messages about attempts to
 
66
 * access unimplemented registers or similar.
 
67
 */
 
68
#define DEBUG_IMPLEMENTATION 1
 
69
#if DEBUG_IMPLEMENTATION
 
70
#  define IPRINTF(fmt, args...) \
 
71
          do { fprintf(stderr, "%s: " fmt, __func__, ##args); } while (0)
 
72
#else
 
73
#  define IPRINTF(fmt, args...) do {} while (0)
 
74
#endif
 
75
 
 
76
#define IMX_GPT(obj) \
 
77
        OBJECT_CHECK(IMXGPTState, (obj), TYPE_IMX_GPT)
 
78
/*
 
79
 * GPT : General purpose timer
 
80
 *
 
81
 * This timer counts up continuously while it is enabled, resetting itself
 
82
 * to 0 when it reaches TIMER_MAX (in freerun mode) or when it
 
83
 * reaches the value of one of the ocrX (in periodic mode).
 
84
 */
 
85
 
 
86
#define TIMER_MAX  0XFFFFFFFFUL
 
87
 
 
88
/* Control register.  Not all of these bits have any effect (yet) */
 
89
#define GPT_CR_EN     (1 << 0)  /* GPT Enable */
 
90
#define GPT_CR_ENMOD  (1 << 1)  /* GPT Enable Mode */
 
91
#define GPT_CR_DBGEN  (1 << 2)  /* GPT Debug mode enable */
 
92
#define GPT_CR_WAITEN (1 << 3)  /* GPT Wait Mode Enable  */
 
93
#define GPT_CR_DOZEN  (1 << 4)  /* GPT Doze mode enable */
 
94
#define GPT_CR_STOPEN (1 << 5)  /* GPT Stop Mode Enable */
 
95
#define GPT_CR_CLKSRC_SHIFT (6)
 
96
#define GPT_CR_CLKSRC_MASK  (0x7)
 
97
 
 
98
#define GPT_CR_FRR    (1 << 9)  /* Freerun or Restart */
 
99
#define GPT_CR_SWR    (1 << 15) /* Software Reset */
 
100
#define GPT_CR_IM1    (3 << 16) /* Input capture channel 1 mode (2 bits) */
 
101
#define GPT_CR_IM2    (3 << 18) /* Input capture channel 2 mode (2 bits) */
 
102
#define GPT_CR_OM1    (7 << 20) /* Output Compare Channel 1 Mode (3 bits) */
 
103
#define GPT_CR_OM2    (7 << 23) /* Output Compare Channel 2 Mode (3 bits) */
 
104
#define GPT_CR_OM3    (7 << 26) /* Output Compare Channel 3 Mode (3 bits) */
 
105
#define GPT_CR_FO1    (1 << 29) /* Force Output Compare Channel 1 */
 
106
#define GPT_CR_FO2    (1 << 30) /* Force Output Compare Channel 2 */
 
107
#define GPT_CR_FO3    (1 << 31) /* Force Output Compare Channel 3 */
 
108
 
 
109
#define GPT_SR_OF1  (1 << 0)
 
110
#define GPT_SR_OF2  (1 << 1)
 
111
#define GPT_SR_OF3  (1 << 2)
 
112
#define GPT_SR_ROV  (1 << 5)
 
113
 
 
114
#define GPT_IR_OF1IE  (1 << 0)
 
115
#define GPT_IR_OF2IE  (1 << 1)
 
116
#define GPT_IR_OF3IE  (1 << 2)
 
117
#define GPT_IR_ROVIE  (1 << 5)
 
118
 
 
119
typedef struct {
 
120
    SysBusDevice busdev;
 
121
    ptimer_state *timer;
 
122
    MemoryRegion iomem;
 
123
    DeviceState *ccm;
 
124
 
 
125
    uint32_t cr;
 
126
    uint32_t pr;
 
127
    uint32_t sr;
 
128
    uint32_t ir;
 
129
    uint32_t ocr1;
 
130
    uint32_t ocr2;
 
131
    uint32_t ocr3;
 
132
    uint32_t icr1;
 
133
    uint32_t icr2;
 
134
    uint32_t cnt;
 
135
 
 
136
    uint32_t next_timeout;
 
137
    uint32_t next_int;
 
138
 
 
139
    uint32_t freq;
 
140
 
 
141
    qemu_irq irq;
 
142
} IMXGPTState;
 
143
 
 
144
static const VMStateDescription vmstate_imx_timer_gpt = {
 
145
    .name = "imx.gpt",
 
146
    .version_id = 3,
 
147
    .minimum_version_id = 3,
 
148
    .minimum_version_id_old = 3,
 
149
    .fields      = (VMStateField[]) {
 
150
        VMSTATE_UINT32(cr, IMXGPTState),
 
151
        VMSTATE_UINT32(pr, IMXGPTState),
 
152
        VMSTATE_UINT32(sr, IMXGPTState),
 
153
        VMSTATE_UINT32(ir, IMXGPTState),
 
154
        VMSTATE_UINT32(ocr1, IMXGPTState),
 
155
        VMSTATE_UINT32(ocr2, IMXGPTState),
 
156
        VMSTATE_UINT32(ocr3, IMXGPTState),
 
157
        VMSTATE_UINT32(icr1, IMXGPTState),
 
158
        VMSTATE_UINT32(icr2, IMXGPTState),
 
159
        VMSTATE_UINT32(cnt, IMXGPTState),
 
160
        VMSTATE_UINT32(next_timeout, IMXGPTState),
 
161
        VMSTATE_UINT32(next_int, IMXGPTState),
 
162
        VMSTATE_UINT32(freq, IMXGPTState),
 
163
        VMSTATE_PTIMER(timer, IMXGPTState),
 
164
        VMSTATE_END_OF_LIST()
 
165
    }
 
166
};
 
167
 
 
168
static const IMXClk imx_gpt_clocks[] = {
 
169
    NOCLK,    /* 000 No clock source */
 
170
    IPG,      /* 001 ipg_clk, 532MHz*/
 
171
    IPG,      /* 010 ipg_clk_highfreq */
 
172
    NOCLK,    /* 011 not defined */
 
173
    CLK_32k,  /* 100 ipg_clk_32k */
 
174
    NOCLK,    /* 101 not defined */
 
175
    NOCLK,    /* 110 not defined */
 
176
    NOCLK,    /* 111 not defined */
 
177
};
 
178
 
 
179
static void imx_gpt_set_freq(IMXGPTState *s)
 
180
{
 
181
    uint32_t clksrc = extract32(s->cr, GPT_CR_CLKSRC_SHIFT, 3);
 
182
    uint32_t freq = imx_clock_frequency(s->ccm, imx_gpt_clocks[clksrc])
 
183
                                                / (1 + s->pr);
 
184
    s->freq = freq;
 
185
 
 
186
    DPRINTF("Setting clksrc %d to frequency %d\n", clksrc, freq);
 
187
 
 
188
    if (freq) {
 
189
        ptimer_set_freq(s->timer, freq);
 
190
    }
 
191
}
 
192
 
 
193
static void imx_gpt_update_int(IMXGPTState *s)
 
194
{
 
195
    if ((s->sr & s->ir) && (s->cr & GPT_CR_EN)) {
 
196
        qemu_irq_raise(s->irq);
 
197
    } else {
 
198
        qemu_irq_lower(s->irq);
 
199
    }
 
200
}
 
201
 
 
202
static uint32_t imx_gpt_update_count(IMXGPTState *s)
 
203
{
 
204
    s->cnt = s->next_timeout - (uint32_t)ptimer_get_count(s->timer);
 
205
 
 
206
    return s->cnt;
 
207
}
 
208
 
 
209
static inline uint32_t imx_gpt_find_limit(uint32_t count, uint32_t reg,
 
210
                                             uint32_t timeout)
 
211
{
 
212
    if ((count < reg) && (timeout > reg)) {
 
213
        timeout = reg;
 
214
    }
 
215
 
 
216
    return timeout;
 
217
}
 
218
 
 
219
static void imx_gpt_compute_next_timeout(IMXGPTState *s, bool event)
 
220
{
 
221
    uint32_t timeout = TIMER_MAX;
 
222
    uint32_t count = 0;
 
223
    long long limit;
 
224
 
 
225
    if (!(s->cr & GPT_CR_EN)) {
 
226
        /* if not enabled just return */
 
227
        return;
 
228
    }
 
229
 
 
230
    if (event) {
 
231
        /* This is a timer event  */
 
232
 
 
233
        if ((s->cr & GPT_CR_FRR)  && (s->next_timeout != TIMER_MAX)) {
 
234
            /*
 
235
             * if we are in free running mode and we have not reached
 
236
             * the TIMER_MAX limit, then update the count
 
237
             */
 
238
            count = imx_gpt_update_count(s);
 
239
        }
 
240
    } else {
 
241
        /* not a timer event, then just update the count */
 
242
 
 
243
        count = imx_gpt_update_count(s);
 
244
    }
 
245
 
 
246
    /* now, find the next timeout related to count */
 
247
 
 
248
    if (s->ir & GPT_IR_OF1IE) {
 
249
        timeout = imx_gpt_find_limit(count, s->ocr1, timeout);
 
250
    }
 
251
    if (s->ir & GPT_IR_OF2IE) {
 
252
        timeout = imx_gpt_find_limit(count, s->ocr2, timeout);
 
253
    }
 
254
    if (s->ir & GPT_IR_OF3IE) {
 
255
        timeout = imx_gpt_find_limit(count, s->ocr3, timeout);
 
256
    }
 
257
 
 
258
    /* find the next set of interrupts to raise for next timer event */
 
259
 
 
260
    s->next_int = 0;
 
261
    if ((s->ir & GPT_IR_OF1IE) && (timeout == s->ocr1)) {
 
262
        s->next_int |= GPT_SR_OF1;
 
263
    }
 
264
    if ((s->ir & GPT_IR_OF2IE) && (timeout == s->ocr2)) {
 
265
        s->next_int |= GPT_SR_OF2;
 
266
    }
 
267
    if ((s->ir & GPT_IR_OF3IE) && (timeout == s->ocr3)) {
 
268
        s->next_int |= GPT_SR_OF3;
 
269
    }
 
270
    if ((s->ir & GPT_IR_ROVIE) && (timeout == TIMER_MAX)) {
 
271
        s->next_int |= GPT_SR_ROV;
 
272
    }
 
273
 
 
274
    /* the new range to count down from */
 
275
    limit = timeout - imx_gpt_update_count(s);
 
276
 
 
277
    if (limit < 0) {
 
278
        /*
 
279
         * if we reach here, then QEMU is running too slow and we pass the
 
280
         * timeout limit while computing it. Let's deliver the interrupt
 
281
         * and compute a new limit.
 
282
         */
 
283
        s->sr |= s->next_int;
 
284
 
 
285
        imx_gpt_compute_next_timeout(s, event);
 
286
 
 
287
        imx_gpt_update_int(s);
 
288
    } else {
 
289
        /* New timeout value */
 
290
        s->next_timeout = timeout;
 
291
 
 
292
        /* reset the limit to the computed range */
 
293
        ptimer_set_limit(s->timer, limit, 1);
 
294
    }
 
295
}
 
296
 
 
297
static uint64_t imx_gpt_read(void *opaque, hwaddr offset, unsigned size)
 
298
{
 
299
    IMXGPTState *s = IMX_GPT(opaque);
 
300
    uint32_t reg_value = 0;
 
301
    uint32_t reg = offset >> 2;
 
302
 
 
303
    switch (reg) {
 
304
    case 0: /* Control Register */
 
305
        reg_value = s->cr;
 
306
        break;
 
307
 
 
308
    case 1: /* prescaler */
 
309
        reg_value = s->pr;
 
310
        break;
 
311
 
 
312
    case 2: /* Status Register */
 
313
        reg_value = s->sr;
 
314
        break;
 
315
 
 
316
    case 3: /* Interrupt Register */
 
317
        reg_value = s->ir;
 
318
        break;
 
319
 
 
320
    case 4: /* Output Compare Register 1 */
 
321
        reg_value = s->ocr1;
 
322
        break;
 
323
 
 
324
    case 5: /* Output Compare Register 2 */
 
325
        reg_value = s->ocr2;
 
326
        break;
 
327
 
 
328
    case 6: /* Output Compare Register 3 */
 
329
        reg_value = s->ocr3;
 
330
        break;
 
331
 
 
332
    case 7: /* input Capture Register 1 */
 
333
        qemu_log_mask(LOG_UNIMP, "icr1 feature is not implemented\n");
 
334
        reg_value = s->icr1;
 
335
        break;
 
336
 
 
337
    case 8: /* input Capture Register 2 */
 
338
        qemu_log_mask(LOG_UNIMP, "icr2 feature is not implemented\n");
 
339
        reg_value = s->icr2;
 
340
        break;
 
341
 
 
342
    case 9: /* cnt */
 
343
        imx_gpt_update_count(s);
 
344
        reg_value = s->cnt;
 
345
        break;
 
346
 
 
347
    default:
 
348
        IPRINTF("Bad offset %x\n", reg);
 
349
        break;
 
350
    }
 
351
 
 
352
    DPRINTF("(%s) = 0x%08x\n", imx_gpt_reg_name(reg), reg_value);
 
353
 
 
354
    return reg_value;
 
355
}
 
356
 
 
357
static void imx_gpt_reset(DeviceState *dev)
 
358
{
 
359
    IMXGPTState *s = IMX_GPT(dev);
 
360
 
 
361
    /* stop timer */
 
362
    ptimer_stop(s->timer);
 
363
 
 
364
    /*
 
365
     * Soft reset doesn't touch some bits; hard reset clears them
 
366
     */
 
367
    s->cr &= ~(GPT_CR_EN|GPT_CR_ENMOD|GPT_CR_STOPEN|GPT_CR_DOZEN|
 
368
               GPT_CR_WAITEN|GPT_CR_DBGEN);
 
369
    s->sr = 0;
 
370
    s->pr = 0;
 
371
    s->ir = 0;
 
372
    s->cnt = 0;
 
373
    s->ocr1 = TIMER_MAX;
 
374
    s->ocr2 = TIMER_MAX;
 
375
    s->ocr3 = TIMER_MAX;
 
376
    s->icr1 = 0;
 
377
    s->icr2 = 0;
 
378
 
 
379
    s->next_timeout = TIMER_MAX;
 
380
    s->next_int = 0;
 
381
 
 
382
    /* compute new freq */
 
383
    imx_gpt_set_freq(s);
 
384
 
 
385
    /* reset the limit to TIMER_MAX */
 
386
    ptimer_set_limit(s->timer, TIMER_MAX, 1);
 
387
 
 
388
    /* if the timer is still enabled, restart it */
 
389
    if (s->freq && (s->cr & GPT_CR_EN)) {
 
390
        ptimer_run(s->timer, 1);
 
391
    }
 
392
}
 
393
 
 
394
static void imx_gpt_write(void *opaque, hwaddr offset, uint64_t value,
 
395
                          unsigned size)
 
396
{
 
397
    IMXGPTState *s = IMX_GPT(opaque);
 
398
    uint32_t oldreg;
 
399
    uint32_t reg = offset >> 2;
 
400
 
 
401
    DPRINTF("(%s, value = 0x%08x)\n", imx_gpt_reg_name(reg),
 
402
            (uint32_t)value);
 
403
 
 
404
    switch (reg) {
 
405
    case 0:
 
406
        oldreg = s->cr;
 
407
        s->cr = value & ~0x7c14;
 
408
        if (s->cr & GPT_CR_SWR) { /* force reset */
 
409
            /* handle the reset */
 
410
            imx_gpt_reset(DEVICE(s));
 
411
        } else {
 
412
            /* set our freq, as the source might have changed */
 
413
            imx_gpt_set_freq(s);
 
414
 
 
415
            if ((oldreg ^ s->cr) & GPT_CR_EN) {
 
416
                if (s->cr & GPT_CR_EN) {
 
417
                    if (s->cr & GPT_CR_ENMOD) {
 
418
                        s->next_timeout = TIMER_MAX;
 
419
                        ptimer_set_count(s->timer, TIMER_MAX);
 
420
                        imx_gpt_compute_next_timeout(s, false);
 
421
                    }
 
422
                    ptimer_run(s->timer, 1);
 
423
                } else {
 
424
                    /* stop timer */
 
425
                    ptimer_stop(s->timer);
 
426
                }
 
427
            }
 
428
        }
 
429
        break;
 
430
 
 
431
    case 1: /* Prescaler */
 
432
        s->pr = value & 0xfff;
 
433
        imx_gpt_set_freq(s);
 
434
        break;
 
435
 
 
436
    case 2: /* SR */
 
437
        s->sr &= ~(value & 0x3f);
 
438
        imx_gpt_update_int(s);
 
439
        break;
 
440
 
 
441
    case 3: /* IR -- interrupt register */
 
442
        s->ir = value & 0x3f;
 
443
        imx_gpt_update_int(s);
 
444
 
 
445
        imx_gpt_compute_next_timeout(s, false);
 
446
 
 
447
        break;
 
448
 
 
449
    case 4: /* OCR1 -- output compare register */
 
450
        s->ocr1 = value;
 
451
 
 
452
        /* In non-freerun mode, reset count when this register is written */
 
453
        if (!(s->cr & GPT_CR_FRR)) {
 
454
            s->next_timeout = TIMER_MAX;
 
455
            ptimer_set_limit(s->timer, TIMER_MAX, 1);
 
456
        }
 
457
 
 
458
        /* compute the new timeout */
 
459
        imx_gpt_compute_next_timeout(s, false);
 
460
 
 
461
        break;
 
462
 
 
463
    case 5: /* OCR2 -- output compare register */
 
464
        s->ocr2 = value;
 
465
 
 
466
        /* compute the new timeout */
 
467
        imx_gpt_compute_next_timeout(s, false);
 
468
 
 
469
        break;
 
470
 
 
471
    case 6: /* OCR3 -- output compare register */
 
472
        s->ocr3 = value;
 
473
 
 
474
        /* compute the new timeout */
 
475
        imx_gpt_compute_next_timeout(s, false);
 
476
 
 
477
        break;
 
478
 
 
479
    default:
 
480
        IPRINTF("Bad offset %x\n", reg);
 
481
        break;
 
482
    }
 
483
}
 
484
 
 
485
static void imx_gpt_timeout(void *opaque)
 
486
{
 
487
    IMXGPTState *s = IMX_GPT(opaque);
 
488
 
 
489
    DPRINTF("\n");
 
490
 
 
491
    s->sr |= s->next_int;
 
492
    s->next_int = 0;
 
493
 
 
494
    imx_gpt_compute_next_timeout(s, true);
 
495
 
 
496
    imx_gpt_update_int(s);
 
497
 
 
498
    if (s->freq && (s->cr & GPT_CR_EN)) {
 
499
        ptimer_run(s->timer, 1);
 
500
    }
 
501
}
 
502
 
 
503
static const MemoryRegionOps imx_gpt_ops = {
 
504
    .read = imx_gpt_read,
 
505
    .write = imx_gpt_write,
 
506
    .endianness = DEVICE_NATIVE_ENDIAN,
 
507
};
 
508
 
 
509
 
 
510
static void imx_gpt_realize(DeviceState *dev, Error **errp)
 
511
{
 
512
    IMXGPTState *s = IMX_GPT(dev);
 
513
    SysBusDevice *sbd = SYS_BUS_DEVICE(dev);
 
514
    QEMUBH *bh;
 
515
 
 
516
    sysbus_init_irq(sbd, &s->irq);
 
517
    memory_region_init_io(&s->iomem, OBJECT(s), &imx_gpt_ops, s, TYPE_IMX_GPT,
 
518
                          0x00001000);
 
519
    sysbus_init_mmio(sbd, &s->iomem);
 
520
 
 
521
    bh = qemu_bh_new(imx_gpt_timeout, s);
 
522
    s->timer = ptimer_init(bh);
 
523
}
 
524
 
 
525
void imx_timerg_create(const hwaddr addr, qemu_irq irq, DeviceState *ccm)
 
526
{
 
527
    IMXGPTState *pp;
 
528
    DeviceState *dev;
 
529
 
 
530
    dev = sysbus_create_simple(TYPE_IMX_GPT, addr, irq);
 
531
    pp = IMX_GPT(dev);
 
532
    pp->ccm = ccm;
 
533
}
 
534
 
 
535
static void imx_gpt_class_init(ObjectClass *klass, void *data)
 
536
{
 
537
    DeviceClass *dc = DEVICE_CLASS(klass);
 
538
 
 
539
    dc->realize = imx_gpt_realize;
 
540
    dc->reset = imx_gpt_reset;
 
541
    dc->vmsd = &vmstate_imx_timer_gpt;
 
542
    dc->desc = "i.MX general timer";
 
543
}
 
544
 
 
545
static const TypeInfo imx_gpt_info = {
 
546
    .name = TYPE_IMX_GPT,
 
547
    .parent = TYPE_SYS_BUS_DEVICE,
 
548
    .instance_size = sizeof(IMXGPTState),
 
549
    .class_init = imx_gpt_class_init,
 
550
};
 
551
 
 
552
static void imx_gpt_register_types(void)
 
553
{
 
554
    type_register_static(&imx_gpt_info);
 
555
}
 
556
 
 
557
type_init(imx_gpt_register_types)