]> Git Repo - qemu.git/blob - hw/imx_timer.c
Allow clock_gettime() monotonic clock to be utilized on more OS's
[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/hw.h"
15 #include "qemu/timer.h"
16 #include "hw/ptimer.h"
17 #include "hw/sysbus.h"
18 #include "hw/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, hwaddr 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, hwaddr 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, hwaddr 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, hwaddr 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 hwaddr 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 hwaddr 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)
This page took 0.060958 seconds and 4 git commands to generate.