]> git.proxmox.com Git - mirror_qemu.git/blob - hw/imx_timer.c
c28c53725ade6cef5be3a653c49b09dab63dbe36
[mirror_qemu.git] / hw / imx_timer.c
1 /*
2 * IMX31 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 *
9 * This code is licensed under GPL version 2 or later. See
10 * the COPYING file in the top-level directory.
11 *
12 */
13
14 #include "hw.h"
15 #include "qemu-timer.h"
16 #include "ptimer.h"
17 #include "sysbus.h"
18 #include "imx.h"
19
20 //#define DEBUG_TIMER 1
21 #ifdef DEBUG_TIMER
22 # define DPRINTF(fmt, args...) \
23 do { printf("imx_timer: " fmt , ##args); } while (0)
24 #else
25 # define DPRINTF(fmt, args...) do {} while (0)
26 #endif
27
28 /*
29 * Define to 1 for messages about attempts to
30 * access unimplemented registers or similar.
31 */
32 #define DEBUG_IMPLEMENTATION 1
33 #if DEBUG_IMPLEMENTATION
34 # define IPRINTF(fmt, args...) \
35 do { fprintf(stderr, "imx_timer: " fmt, ##args); } while (0)
36 #else
37 # define IPRINTF(fmt, args...) do {} while (0)
38 #endif
39
40 /*
41 * GPT : General purpose timer
42 *
43 * This timer counts up continuously while it is enabled, resetting itself
44 * to 0 when it reaches TIMER_MAX (in freerun mode) or when it
45 * reaches the value of ocr1 (in periodic mode). WE simulate this using a
46 * QEMU ptimer counting down from ocr1 and reloading from ocr1 in
47 * periodic mode, or counting from ocr1 to zero, then TIMER_MAX - ocr1.
48 * waiting_rov is set when counting from TIMER_MAX.
49 *
50 * In the real hardware, there are three comparison registers that can
51 * trigger interrupts, and compare channel 1 can be used to
52 * force-reset the timer. However, this is a `bare-bones'
53 * implementation: only what Linux 3.x uses has been implemented
54 * (free-running timer from 0 to OCR1 or TIMER_MAX) .
55 */
56
57
58 #define TIMER_MAX 0XFFFFFFFFUL
59
60 /* Control register. Not all of these bits have any effect (yet) */
61 #define GPT_CR_EN (1 << 0) /* GPT Enable */
62 #define GPT_CR_ENMOD (1 << 1) /* GPT Enable Mode */
63 #define GPT_CR_DBGEN (1 << 2) /* GPT Debug mode enable */
64 #define GPT_CR_WAITEN (1 << 3) /* GPT Wait Mode Enable */
65 #define GPT_CR_DOZEN (1 << 4) /* GPT Doze mode enable */
66 #define GPT_CR_STOPEN (1 << 5) /* GPT Stop Mode Enable */
67 #define GPT_CR_CLKSRC_SHIFT (6)
68 #define GPT_CR_CLKSRC_MASK (0x7)
69
70 #define GPT_CR_FRR (1 << 9) /* Freerun or Restart */
71 #define GPT_CR_SWR (1 << 15) /* Software Reset */
72 #define GPT_CR_IM1 (3 << 16) /* Input capture channel 1 mode (2 bits) */
73 #define GPT_CR_IM2 (3 << 18) /* Input capture channel 2 mode (2 bits) */
74 #define GPT_CR_OM1 (7 << 20) /* Output Compare Channel 1 Mode (3 bits) */
75 #define GPT_CR_OM2 (7 << 23) /* Output Compare Channel 2 Mode (3 bits) */
76 #define GPT_CR_OM3 (7 << 26) /* Output Compare Channel 3 Mode (3 bits) */
77 #define GPT_CR_FO1 (1 << 29) /* Force Output Compare Channel 1 */
78 #define GPT_CR_FO2 (1 << 30) /* Force Output Compare Channel 2 */
79 #define GPT_CR_FO3 (1 << 31) /* Force Output Compare Channel 3 */
80
81 #define GPT_SR_OF1 (1 << 0)
82 #define GPT_SR_ROV (1 << 5)
83
84 #define GPT_IR_OF1IE (1 << 0)
85 #define GPT_IR_ROVIE (1 << 5)
86
87 typedef struct {
88 SysBusDevice busdev;
89 ptimer_state *timer;
90 MemoryRegion iomem;
91 DeviceState *ccm;
92
93 uint32_t cr;
94 uint32_t pr;
95 uint32_t sr;
96 uint32_t ir;
97 uint32_t ocr1;
98 uint32_t cnt;
99
100 uint32_t waiting_rov;
101 qemu_irq irq;
102 } IMXTimerGState;
103
104 static const VMStateDescription vmstate_imx_timerg = {
105 .name = "imx-timerg",
106 .version_id = 1,
107 .minimum_version_id = 1,
108 .minimum_version_id_old = 1,
109 .fields = (VMStateField[]) {
110 VMSTATE_UINT32(cr, IMXTimerGState),
111 VMSTATE_UINT32(pr, IMXTimerGState),
112 VMSTATE_UINT32(sr, IMXTimerGState),
113 VMSTATE_UINT32(ir, IMXTimerGState),
114 VMSTATE_UINT32(ocr1, IMXTimerGState),
115 VMSTATE_UINT32(cnt, IMXTimerGState),
116 VMSTATE_UINT32(waiting_rov, IMXTimerGState),
117 VMSTATE_PTIMER(timer, IMXTimerGState),
118 VMSTATE_END_OF_LIST()
119 }
120 };
121
122 static const IMXClk imx_timerg_clocks[] = {
123 NOCLK, /* 000 No clock source */
124 IPG, /* 001 ipg_clk, 532MHz*/
125 IPG, /* 010 ipg_clk_highfreq */
126 NOCLK, /* 011 not defined */
127 CLK_32k, /* 100 ipg_clk_32k */
128 NOCLK, /* 101 not defined */
129 NOCLK, /* 110 not defined */
130 NOCLK, /* 111 not defined */
131 };
132
133
134 static void imx_timerg_set_freq(IMXTimerGState *s)
135 {
136 int clksrc;
137 uint32_t freq;
138
139 clksrc = (s->cr >> GPT_CR_CLKSRC_SHIFT) & GPT_CR_CLKSRC_MASK;
140 freq = imx_clock_frequency(s->ccm, imx_timerg_clocks[clksrc]) / (1 + s->pr);
141
142 DPRINTF("Setting gtimer clksrc %d to frequency %d\n", clksrc, freq);
143 if (freq) {
144 ptimer_set_freq(s->timer, freq);
145 }
146 }
147
148 static void imx_timerg_update(IMXTimerGState *s)
149 {
150 uint32_t flags = s->sr & s->ir & (GPT_SR_OF1 | GPT_SR_ROV);
151
152 DPRINTF("g-timer SR: %s %s IR=%s %s, %s\n",
153 s->sr & GPT_SR_OF1 ? "OF1" : "",
154 s->sr & GPT_SR_ROV ? "ROV" : "",
155 s->ir & GPT_SR_OF1 ? "OF1" : "",
156 s->ir & GPT_SR_ROV ? "ROV" : "",
157 s->cr & GPT_CR_EN ? "CR_EN" : "Not Enabled");
158
159
160 qemu_set_irq(s->irq, (s->cr & GPT_CR_EN) && flags);
161 }
162
163 static uint32_t imx_timerg_update_counts(IMXTimerGState *s)
164 {
165 uint64_t target = s->waiting_rov ? TIMER_MAX : s->ocr1;
166 uint64_t cnt = ptimer_get_count(s->timer);
167 s->cnt = target - cnt;
168 return s->cnt;
169 }
170
171 static void imx_timerg_reload(IMXTimerGState *s, uint32_t timeout)
172 {
173 uint64_t diff_cnt;
174
175 if (!(s->cr & GPT_CR_FRR)) {
176 IPRINTF("IMX_timerg_reload --- called in reset-mode\n");
177 return;
178 }
179
180 /*
181 * For small timeouts, qemu sometimes runs too slow.
182 * Better deliver a late interrupt than none.
183 *
184 * In Reset mode (FRR bit clear)
185 * the ptimer reloads itself from OCR1;
186 * in free-running mode we need to fake
187 * running from 0 to ocr1 to TIMER_MAX
188 */
189 if (timeout > s->cnt) {
190 diff_cnt = timeout - s->cnt;
191 } else {
192 diff_cnt = 0;
193 }
194 ptimer_set_count(s->timer, diff_cnt);
195 }
196
197 static uint64_t imx_timerg_read(void *opaque, target_phys_addr_t offset,
198 unsigned size)
199 {
200 IMXTimerGState *s = (IMXTimerGState *)opaque;
201
202 DPRINTF("g-read(offset=%x)", offset >> 2);
203 switch (offset >> 2) {
204 case 0: /* Control Register */
205 DPRINTF(" cr = %x\n", s->cr);
206 return s->cr;
207
208 case 1: /* prescaler */
209 DPRINTF(" pr = %x\n", s->pr);
210 return s->pr;
211
212 case 2: /* Status Register */
213 DPRINTF(" sr = %x\n", s->sr);
214 return s->sr;
215
216 case 3: /* Interrupt Register */
217 DPRINTF(" ir = %x\n", s->ir);
218 return s->ir;
219
220 case 4: /* Output Compare Register 1 */
221 DPRINTF(" ocr1 = %x\n", s->ocr1);
222 return s->ocr1;
223
224
225 case 9: /* cnt */
226 imx_timerg_update_counts(s);
227 DPRINTF(" cnt = %x\n", s->cnt);
228 return s->cnt;
229 }
230
231 IPRINTF("imx_timerg_read: Bad offset %x\n",
232 (int)offset >> 2);
233 return 0;
234 }
235
236 static void imx_timerg_reset(DeviceState *dev)
237 {
238 IMXTimerGState *s = container_of(dev, IMXTimerGState, busdev.qdev);
239
240 /*
241 * Soft reset doesn't touch some bits; hard reset clears them
242 */
243 s->cr &= ~(GPT_CR_EN|GPT_CR_DOZEN|GPT_CR_WAITEN|GPT_CR_DBGEN);
244 s->sr = 0;
245 s->pr = 0;
246 s->ir = 0;
247 s->cnt = 0;
248 s->ocr1 = TIMER_MAX;
249 ptimer_stop(s->timer);
250 ptimer_set_limit(s->timer, TIMER_MAX, 1);
251 imx_timerg_set_freq(s);
252 }
253
254 static void imx_timerg_write(void *opaque, target_phys_addr_t offset,
255 uint64_t value, unsigned size)
256 {
257 IMXTimerGState *s = (IMXTimerGState *)opaque;
258 DPRINTF("g-write(offset=%x, value = 0x%x)\n", (unsigned int)offset >> 2,
259 (unsigned int)value);
260
261 switch (offset >> 2) {
262 case 0: {
263 uint32_t oldcr = s->cr;
264 /* CR */
265 if (value & GPT_CR_SWR) { /* force reset */
266 value &= ~GPT_CR_SWR;
267 imx_timerg_reset(&s->busdev.qdev);
268 imx_timerg_update(s);
269 }
270
271 s->cr = value & ~0x7c00;
272 imx_timerg_set_freq(s);
273 if ((oldcr ^ value) & GPT_CR_EN) {
274 if (value & GPT_CR_EN) {
275 if (value & GPT_CR_ENMOD) {
276 ptimer_set_count(s->timer, s->ocr1);
277 s->cnt = 0;
278 }
279 ptimer_run(s->timer,
280 (value & GPT_CR_FRR) && (s->ocr1 != TIMER_MAX));
281 } else {
282 ptimer_stop(s->timer);
283 };
284 }
285 return;
286 }
287
288 case 1: /* Prescaler */
289 s->pr = value & 0xfff;
290 imx_timerg_set_freq(s);
291 return;
292
293 case 2: /* SR */
294 /*
295 * No point in implementing the status register bits to do with
296 * external interrupt sources.
297 */
298 value &= GPT_SR_OF1 | GPT_SR_ROV;
299 s->sr &= ~value;
300 imx_timerg_update(s);
301 return;
302
303 case 3: /* IR -- interrupt register */
304 s->ir = value & 0x3f;
305 imx_timerg_update(s);
306 return;
307
308 case 4: /* OCR1 -- output compare register */
309 /* In non-freerun mode, reset count when this register is written */
310 if (!(s->cr & GPT_CR_FRR)) {
311 s->waiting_rov = 0;
312 ptimer_set_limit(s->timer, value, 1);
313 } else {
314 imx_timerg_update_counts(s);
315 if (value > s->cnt) {
316 s->waiting_rov = 0;
317 imx_timerg_reload(s, value);
318 } else {
319 s->waiting_rov = 1;
320 imx_timerg_reload(s, TIMER_MAX - s->cnt);
321 }
322 }
323 s->ocr1 = value;
324 return;
325
326 default:
327 IPRINTF("imx_timerg_write: Bad offset %x\n",
328 (int)offset >> 2);
329 }
330 }
331
332 static void imx_timerg_timeout(void *opaque)
333 {
334 IMXTimerGState *s = (IMXTimerGState *)opaque;
335
336 DPRINTF("imx_timerg_timeout, waiting rov=%d\n", s->waiting_rov);
337 if (s->cr & GPT_CR_FRR) {
338 /*
339 * Free running timer from 0 -> TIMERMAX
340 * Generates interrupt at TIMER_MAX and at cnt==ocr1
341 * If ocr1 == TIMER_MAX, then no need to reload timer.
342 */
343 if (s->ocr1 == TIMER_MAX) {
344 DPRINTF("s->ocr1 == TIMER_MAX, FRR\n");
345 s->sr |= GPT_SR_OF1 | GPT_SR_ROV;
346 imx_timerg_update(s);
347 return;
348 }
349
350 if (s->waiting_rov) {
351 /*
352 * We were waiting for cnt==TIMER_MAX
353 */
354 s->sr |= GPT_SR_ROV;
355 s->waiting_rov = 0;
356 s->cnt = 0;
357 imx_timerg_reload(s, s->ocr1);
358 } else {
359 /* Must have got a cnt==ocr1 timeout. */
360 s->sr |= GPT_SR_OF1;
361 s->cnt = s->ocr1;
362 s->waiting_rov = 1;
363 imx_timerg_reload(s, TIMER_MAX);
364 }
365 imx_timerg_update(s);
366 return;
367 }
368
369 s->sr |= GPT_SR_OF1;
370 imx_timerg_update(s);
371 }
372
373 static const MemoryRegionOps imx_timerg_ops = {
374 .read = imx_timerg_read,
375 .write = imx_timerg_write,
376 .endianness = DEVICE_NATIVE_ENDIAN,
377 };
378
379
380 static int imx_timerg_init(SysBusDevice *dev)
381 {
382 IMXTimerGState *s = FROM_SYSBUS(IMXTimerGState, dev);
383 QEMUBH *bh;
384
385 sysbus_init_irq(dev, &s->irq);
386 memory_region_init_io(&s->iomem, &imx_timerg_ops,
387 s, "imxg-timer",
388 0x00001000);
389 sysbus_init_mmio(dev, &s->iomem);
390
391 bh = qemu_bh_new(imx_timerg_timeout, s);
392 s->timer = ptimer_init(bh);
393
394 /* Hard reset resets extra bits in CR */
395 s->cr = 0;
396 return 0;
397 }
398
399
400
401 /*
402 * EPIT: Enhanced periodic interrupt timer
403 */
404
405 #define CR_EN (1 << 0)
406 #define CR_ENMOD (1 << 1)
407 #define CR_OCIEN (1 << 2)
408 #define CR_RLD (1 << 3)
409 #define CR_PRESCALE_SHIFT (4)
410 #define CR_PRESCALE_MASK (0xfff)
411 #define CR_SWR (1 << 16)
412 #define CR_IOVW (1 << 17)
413 #define CR_DBGEN (1 << 18)
414 #define CR_EPIT (1 << 19)
415 #define CR_DOZEN (1 << 20)
416 #define CR_STOPEN (1 << 21)
417 #define CR_CLKSRC_SHIFT (24)
418 #define CR_CLKSRC_MASK (0x3 << CR_CLKSRC_SHIFT)
419
420
421 /*
422 * Exact clock frequencies vary from board to board.
423 * These are typical.
424 */
425 static const IMXClk imx_timerp_clocks[] = {
426 0, /* disabled */
427 IPG, /* ipg_clk, ~532MHz */
428 IPG, /* ipg_clk_highfreq */
429 CLK_32k, /* ipg_clk_32k -- ~32kHz */
430 };
431
432 typedef struct {
433 SysBusDevice busdev;
434 ptimer_state *timer;
435 MemoryRegion iomem;
436 DeviceState *ccm;
437
438 uint32_t cr;
439 uint32_t lr;
440 uint32_t cmp;
441
442 uint32_t freq;
443 int int_level;
444 qemu_irq irq;
445 } IMXTimerPState;
446
447 /*
448 * Update interrupt status
449 */
450 static void imx_timerp_update(IMXTimerPState *s)
451 {
452 if (s->int_level && (s->cr & CR_OCIEN)) {
453 qemu_irq_raise(s->irq);
454 } else {
455 qemu_irq_lower(s->irq);
456 }
457 }
458
459 static void imx_timerp_reset(DeviceState *dev)
460 {
461 IMXTimerPState *s = container_of(dev, IMXTimerPState, busdev.qdev);
462
463 s->cr = 0;
464 s->lr = TIMER_MAX;
465 s->int_level = 0;
466 s->cmp = 0;
467 ptimer_stop(s->timer);
468 ptimer_set_count(s->timer, TIMER_MAX);
469 }
470
471 static uint64_t imx_timerp_read(void *opaque, target_phys_addr_t offset,
472 unsigned size)
473 {
474 IMXTimerPState *s = (IMXTimerPState *)opaque;
475
476 DPRINTF("p-read(offset=%x)", offset >> 2);
477 switch (offset >> 2) {
478 case 0: /* Control Register */
479 DPRINTF("cr %x\n", s->cr);
480 return s->cr;
481
482 case 1: /* Status Register */
483 DPRINTF("int_level %x\n", s->int_level);
484 return s->int_level;
485
486 case 2: /* LR - ticks*/
487 DPRINTF("lr %x\n", s->lr);
488 return s->lr;
489
490 case 3: /* CMP */
491 DPRINTF("cmp %x\n", s->cmp);
492 return s->cmp;
493
494 case 4: /* CNT */
495 return ptimer_get_count(s->timer);
496 }
497 IPRINTF("imx_timerp_read: Bad offset %x\n",
498 (int)offset >> 2);
499 return 0;
500 }
501
502 static void set_timerp_freq(IMXTimerPState *s)
503 {
504 int clksrc;
505 unsigned prescaler;
506 uint32_t freq;
507
508 clksrc = (s->cr & CR_CLKSRC_MASK) >> CR_CLKSRC_SHIFT;
509 prescaler = 1 + ((s->cr >> CR_PRESCALE_SHIFT) & CR_PRESCALE_MASK);
510 freq = imx_clock_frequency(s->ccm, imx_timerp_clocks[clksrc]) / prescaler;
511
512 s->freq = freq;
513 DPRINTF("Setting ptimer frequency to %u\n", freq);
514
515 if (freq) {
516 ptimer_set_freq(s->timer, freq);
517 }
518 }
519
520 static void imx_timerp_write(void *opaque, target_phys_addr_t offset,
521 uint64_t value, unsigned size)
522 {
523 IMXTimerPState *s = (IMXTimerPState *)opaque;
524 DPRINTF("p-write(offset=%x, value = %x)\n", (unsigned int)offset >> 2,
525 (unsigned int)value);
526
527 switch (offset >> 2) {
528 case 0: /* CR */
529 if (value & CR_SWR) {
530 imx_timerp_reset(&s->busdev.qdev);
531 value &= ~CR_SWR;
532 }
533 s->cr = value & 0x03ffffff;
534 set_timerp_freq(s);
535
536 if (s->freq && (s->cr & CR_EN)) {
537 if (!(s->cr & CR_ENMOD)) {
538 ptimer_set_count(s->timer, s->lr);
539 }
540 ptimer_run(s->timer, 0);
541 } else {
542 ptimer_stop(s->timer);
543 }
544 break;
545
546 case 1: /* SR - ACK*/
547 s->int_level = 0;
548 imx_timerp_update(s);
549 break;
550
551 case 2: /* LR - set ticks */
552 s->lr = value;
553 ptimer_set_limit(s->timer, value, !!(s->cr & CR_IOVW));
554 break;
555
556 case 3: /* CMP */
557 s->cmp = value;
558 if (value) {
559 IPRINTF(
560 "Values for EPIT comparison other than zero not supported\n"
561 );
562 }
563 break;
564
565 default:
566 IPRINTF("imx_timerp_write: Bad offset %x\n",
567 (int)offset >> 2);
568 }
569 }
570
571 static void imx_timerp_tick(void *opaque)
572 {
573 IMXTimerPState *s = (IMXTimerPState *)opaque;
574
575 DPRINTF("imxp tick\n");
576 if (!(s->cr & CR_RLD)) {
577 ptimer_set_count(s->timer, TIMER_MAX);
578 }
579 s->int_level = 1;
580 imx_timerp_update(s);
581 }
582
583 void imx_timerp_create(const target_phys_addr_t addr,
584 qemu_irq irq,
585 DeviceState *ccm)
586 {
587 IMXTimerPState *pp;
588 DeviceState *dev;
589
590 dev = sysbus_create_simple("imx_timerp", addr, irq);
591 pp = container_of(dev, IMXTimerPState, busdev.qdev);
592 pp->ccm = ccm;
593 }
594
595 static const MemoryRegionOps imx_timerp_ops = {
596 .read = imx_timerp_read,
597 .write = imx_timerp_write,
598 .endianness = DEVICE_NATIVE_ENDIAN,
599 };
600
601 static const VMStateDescription vmstate_imx_timerp = {
602 .name = "imx-timerp",
603 .version_id = 1,
604 .minimum_version_id = 1,
605 .minimum_version_id_old = 1,
606 .fields = (VMStateField[]) {
607 VMSTATE_UINT32(cr, IMXTimerPState),
608 VMSTATE_UINT32(lr, IMXTimerPState),
609 VMSTATE_UINT32(cmp, IMXTimerPState),
610 VMSTATE_UINT32(freq, IMXTimerPState),
611 VMSTATE_INT32(int_level, IMXTimerPState),
612 VMSTATE_PTIMER(timer, IMXTimerPState),
613 VMSTATE_END_OF_LIST()
614 }
615 };
616
617 static int imx_timerp_init(SysBusDevice *dev)
618 {
619 IMXTimerPState *s = FROM_SYSBUS(IMXTimerPState, dev);
620 QEMUBH *bh;
621
622 DPRINTF("imx_timerp_init\n");
623
624 sysbus_init_irq(dev, &s->irq);
625 memory_region_init_io(&s->iomem, &imx_timerp_ops,
626 s, "imxp-timer",
627 0x00001000);
628 sysbus_init_mmio(dev, &s->iomem);
629
630 bh = qemu_bh_new(imx_timerp_tick, s);
631 s->timer = ptimer_init(bh);
632
633 return 0;
634 }
635
636
637 void imx_timerg_create(const target_phys_addr_t addr,
638 qemu_irq irq,
639 DeviceState *ccm)
640 {
641 IMXTimerGState *pp;
642 DeviceState *dev;
643
644 dev = sysbus_create_simple("imx_timerg", addr, irq);
645 pp = container_of(dev, IMXTimerGState, busdev.qdev);
646 pp->ccm = ccm;
647 }
648
649 static void imx_timerg_class_init(ObjectClass *klass, void *data)
650 {
651 DeviceClass *dc = DEVICE_CLASS(klass);
652 SysBusDeviceClass *k = SYS_BUS_DEVICE_CLASS(klass);
653 k->init = imx_timerg_init;
654 dc->vmsd = &vmstate_imx_timerg;
655 dc->reset = imx_timerg_reset;
656 dc->desc = "i.MX general timer";
657 }
658
659 static void imx_timerp_class_init(ObjectClass *klass, void *data)
660 {
661 DeviceClass *dc = DEVICE_CLASS(klass);
662 SysBusDeviceClass *k = SYS_BUS_DEVICE_CLASS(klass);
663 k->init = imx_timerp_init;
664 dc->vmsd = &vmstate_imx_timerp;
665 dc->reset = imx_timerp_reset;
666 dc->desc = "i.MX periodic timer";
667 }
668
669 static const TypeInfo imx_timerp_info = {
670 .name = "imx_timerp",
671 .parent = TYPE_SYS_BUS_DEVICE,
672 .instance_size = sizeof(IMXTimerPState),
673 .class_init = imx_timerp_class_init,
674 };
675
676 static const TypeInfo imx_timerg_info = {
677 .name = "imx_timerg",
678 .parent = TYPE_SYS_BUS_DEVICE,
679 .instance_size = sizeof(IMXTimerGState),
680 .class_init = imx_timerg_class_init,
681 };
682
683 static void imx_timer_register_types(void)
684 {
685 type_register_static(&imx_timerp_info);
686 type_register_static(&imx_timerg_info);
687 }
688
689 type_init(imx_timer_register_types)