qemu

FORK: QEMU emulator
git clone https://git.neptards.moe/neptards/qemu.git
Log | Files | Refs | Submodules | LICENSE

imx_gpt.c (15569B)


      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 <jcd@tribudubois.net>
      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 "qemu/osdep.h"
     16 #include "hw/irq.h"
     17 #include "hw/timer/imx_gpt.h"
     18 #include "migration/vmstate.h"
     19 #include "qemu/module.h"
     20 #include "qemu/log.h"
     21 
     22 #ifndef DEBUG_IMX_GPT
     23 #define DEBUG_IMX_GPT 0
     24 #endif
     25 
     26 #define DPRINTF(fmt, args...) \
     27     do { \
     28         if (DEBUG_IMX_GPT) { \
     29             fprintf(stderr, "[%s]%s: " fmt , TYPE_IMX_GPT, \
     30                                              __func__, ##args); \
     31         } \
     32     } while (0)
     33 
     34 static const char *imx_gpt_reg_name(uint32_t reg)
     35 {
     36     switch (reg) {
     37     case 0:
     38         return "CR";
     39     case 1:
     40         return "PR";
     41     case 2:
     42         return "SR";
     43     case 3:
     44         return "IR";
     45     case 4:
     46         return "OCR1";
     47     case 5:
     48         return "OCR2";
     49     case 6:
     50         return "OCR3";
     51     case 7:
     52         return "ICR1";
     53     case 8:
     54         return "ICR2";
     55     case 9:
     56         return "CNT";
     57     default:
     58         return "[?]";
     59     }
     60 }
     61 
     62 static const VMStateDescription vmstate_imx_timer_gpt = {
     63     .name = TYPE_IMX_GPT,
     64     .version_id = 3,
     65     .minimum_version_id = 3,
     66     .fields = (VMStateField[]) {
     67         VMSTATE_UINT32(cr, IMXGPTState),
     68         VMSTATE_UINT32(pr, IMXGPTState),
     69         VMSTATE_UINT32(sr, IMXGPTState),
     70         VMSTATE_UINT32(ir, IMXGPTState),
     71         VMSTATE_UINT32(ocr1, IMXGPTState),
     72         VMSTATE_UINT32(ocr2, IMXGPTState),
     73         VMSTATE_UINT32(ocr3, IMXGPTState),
     74         VMSTATE_UINT32(icr1, IMXGPTState),
     75         VMSTATE_UINT32(icr2, IMXGPTState),
     76         VMSTATE_UINT32(cnt, IMXGPTState),
     77         VMSTATE_UINT32(next_timeout, IMXGPTState),
     78         VMSTATE_UINT32(next_int, IMXGPTState),
     79         VMSTATE_UINT32(freq, IMXGPTState),
     80         VMSTATE_PTIMER(timer, IMXGPTState),
     81         VMSTATE_END_OF_LIST()
     82     }
     83 };
     84 
     85 static const IMXClk imx25_gpt_clocks[] = {
     86     CLK_NONE,      /* 000 No clock source */
     87     CLK_IPG,       /* 001 ipg_clk, 532MHz*/
     88     CLK_IPG_HIGH,  /* 010 ipg_clk_highfreq */
     89     CLK_NONE,      /* 011 not defined */
     90     CLK_32k,       /* 100 ipg_clk_32k */
     91     CLK_32k,       /* 101 ipg_clk_32k */
     92     CLK_32k,       /* 110 ipg_clk_32k */
     93     CLK_32k,       /* 111 ipg_clk_32k */
     94 };
     95 
     96 static const IMXClk imx31_gpt_clocks[] = {
     97     CLK_NONE,      /* 000 No clock source */
     98     CLK_IPG,       /* 001 ipg_clk, 532MHz*/
     99     CLK_IPG_HIGH,  /* 010 ipg_clk_highfreq */
    100     CLK_NONE,      /* 011 not defined */
    101     CLK_32k,       /* 100 ipg_clk_32k */
    102     CLK_NONE,      /* 101 not defined */
    103     CLK_NONE,      /* 110 not defined */
    104     CLK_NONE,      /* 111 not defined */
    105 };
    106 
    107 static const IMXClk imx6_gpt_clocks[] = {
    108     CLK_NONE,      /* 000 No clock source */
    109     CLK_IPG,       /* 001 ipg_clk, 532MHz*/
    110     CLK_IPG_HIGH,  /* 010 ipg_clk_highfreq */
    111     CLK_EXT,       /* 011 External clock */
    112     CLK_32k,       /* 100 ipg_clk_32k */
    113     CLK_HIGH_DIV,  /* 101 reference clock / 8 */
    114     CLK_NONE,      /* 110 not defined */
    115     CLK_HIGH,      /* 111 reference clock */
    116 };
    117 
    118 static const IMXClk imx7_gpt_clocks[] = {
    119     CLK_NONE,      /* 000 No clock source */
    120     CLK_IPG,       /* 001 ipg_clk, 532MHz*/
    121     CLK_IPG_HIGH,  /* 010 ipg_clk_highfreq */
    122     CLK_EXT,       /* 011 External clock */
    123     CLK_32k,       /* 100 ipg_clk_32k */
    124     CLK_HIGH,      /* 101 reference clock */
    125     CLK_NONE,      /* 110 not defined */
    126     CLK_NONE,      /* 111 not defined */
    127 };
    128 
    129 /* Must be called from within ptimer_transaction_begin/commit block */
    130 static void imx_gpt_set_freq(IMXGPTState *s)
    131 {
    132     uint32_t clksrc = extract32(s->cr, GPT_CR_CLKSRC_SHIFT, 3);
    133 
    134     s->freq = imx_ccm_get_clock_frequency(s->ccm,
    135                                           s->clocks[clksrc]) / (1 + s->pr);
    136 
    137     DPRINTF("Setting clksrc %d to frequency %d\n", clksrc, s->freq);
    138 
    139     if (s->freq) {
    140         ptimer_set_freq(s->timer, s->freq);
    141     }
    142 }
    143 
    144 static void imx_gpt_update_int(IMXGPTState *s)
    145 {
    146     if ((s->sr & s->ir) && (s->cr & GPT_CR_EN)) {
    147         qemu_irq_raise(s->irq);
    148     } else {
    149         qemu_irq_lower(s->irq);
    150     }
    151 }
    152 
    153 static uint32_t imx_gpt_update_count(IMXGPTState *s)
    154 {
    155     s->cnt = s->next_timeout - (uint32_t)ptimer_get_count(s->timer);
    156 
    157     return s->cnt;
    158 }
    159 
    160 static inline uint32_t imx_gpt_find_limit(uint32_t count, uint32_t reg,
    161                                           uint32_t timeout)
    162 {
    163     if ((count < reg) && (timeout > reg)) {
    164         timeout = reg;
    165     }
    166 
    167     return timeout;
    168 }
    169 
    170 /* Must be called from within ptimer_transaction_begin/commit block */
    171 static void imx_gpt_compute_next_timeout(IMXGPTState *s, bool event)
    172 {
    173     uint32_t timeout = GPT_TIMER_MAX;
    174     uint32_t count;
    175     long long limit;
    176 
    177     if (!(s->cr & GPT_CR_EN)) {
    178         /* if not enabled just return */
    179         return;
    180     }
    181 
    182     /* update the count */
    183     count = imx_gpt_update_count(s);
    184 
    185     if (event) {
    186         /*
    187          * This is an event (the ptimer reached 0 and stopped), and the
    188          * timer counter is now equal to s->next_timeout.
    189          */
    190         if (!(s->cr & GPT_CR_FRR) && (count == s->ocr1)) {
    191             /* We are in restart mode and we crossed the compare channel 1
    192              * value. We need to reset the counter to 0.
    193              */
    194             count = s->cnt = s->next_timeout = 0;
    195         } else if (count == GPT_TIMER_MAX) {
    196             /* We reached GPT_TIMER_MAX so we need to rollover */
    197             count = s->cnt = s->next_timeout = 0;
    198         }
    199     }
    200 
    201     /* now, find the next timeout related to count */
    202 
    203     if (s->ir & GPT_IR_OF1IE) {
    204         timeout = imx_gpt_find_limit(count, s->ocr1, timeout);
    205     }
    206     if (s->ir & GPT_IR_OF2IE) {
    207         timeout = imx_gpt_find_limit(count, s->ocr2, timeout);
    208     }
    209     if (s->ir & GPT_IR_OF3IE) {
    210         timeout = imx_gpt_find_limit(count, s->ocr3, timeout);
    211     }
    212 
    213     /* find the next set of interrupts to raise for next timer event */
    214 
    215     s->next_int = 0;
    216     if ((s->ir & GPT_IR_OF1IE) && (timeout == s->ocr1)) {
    217         s->next_int |= GPT_SR_OF1;
    218     }
    219     if ((s->ir & GPT_IR_OF2IE) && (timeout == s->ocr2)) {
    220         s->next_int |= GPT_SR_OF2;
    221     }
    222     if ((s->ir & GPT_IR_OF3IE) && (timeout == s->ocr3)) {
    223         s->next_int |= GPT_SR_OF3;
    224     }
    225     if ((s->ir & GPT_IR_ROVIE) && (timeout == GPT_TIMER_MAX)) {
    226         s->next_int |= GPT_SR_ROV;
    227     }
    228 
    229     /* the new range to count down from */
    230     limit = timeout - imx_gpt_update_count(s);
    231 
    232     if (limit < 0) {
    233         /*
    234          * if we reach here, then QEMU is running too slow and we pass the
    235          * timeout limit while computing it. Let's deliver the interrupt
    236          * and compute a new limit.
    237          */
    238         s->sr |= s->next_int;
    239 
    240         imx_gpt_compute_next_timeout(s, event);
    241 
    242         imx_gpt_update_int(s);
    243     } else {
    244         /* New timeout value */
    245         s->next_timeout = timeout;
    246 
    247         /* reset the limit to the computed range */
    248         ptimer_set_limit(s->timer, limit, 1);
    249     }
    250 }
    251 
    252 static uint64_t imx_gpt_read(void *opaque, hwaddr offset, unsigned size)
    253 {
    254     IMXGPTState *s = IMX_GPT(opaque);
    255     uint32_t reg_value = 0;
    256 
    257     switch (offset >> 2) {
    258     case 0: /* Control Register */
    259         reg_value = s->cr;
    260         break;
    261 
    262     case 1: /* prescaler */
    263         reg_value = s->pr;
    264         break;
    265 
    266     case 2: /* Status Register */
    267         reg_value = s->sr;
    268         break;
    269 
    270     case 3: /* Interrupt Register */
    271         reg_value = s->ir;
    272         break;
    273 
    274     case 4: /* Output Compare Register 1 */
    275         reg_value = s->ocr1;
    276         break;
    277 
    278     case 5: /* Output Compare Register 2 */
    279         reg_value = s->ocr2;
    280         break;
    281 
    282     case 6: /* Output Compare Register 3 */
    283         reg_value = s->ocr3;
    284         break;
    285 
    286     case 7: /* input Capture Register 1 */
    287         qemu_log_mask(LOG_UNIMP, "[%s]%s: icr1 feature is not implemented\n",
    288                       TYPE_IMX_GPT, __func__);
    289         reg_value = s->icr1;
    290         break;
    291 
    292     case 8: /* input Capture Register 2 */
    293         qemu_log_mask(LOG_UNIMP, "[%s]%s: icr2 feature is not implemented\n",
    294                       TYPE_IMX_GPT, __func__);
    295         reg_value = s->icr2;
    296         break;
    297 
    298     case 9: /* cnt */
    299         imx_gpt_update_count(s);
    300         reg_value = s->cnt;
    301         break;
    302 
    303     default:
    304         qemu_log_mask(LOG_GUEST_ERROR, "[%s]%s: Bad register at offset 0x%"
    305                       HWADDR_PRIx "\n", TYPE_IMX_GPT, __func__, offset);
    306         break;
    307     }
    308 
    309     DPRINTF("(%s) = 0x%08x\n", imx_gpt_reg_name(offset >> 2), reg_value);
    310 
    311     return reg_value;
    312 }
    313 
    314 
    315 static void imx_gpt_reset_common(IMXGPTState *s, bool is_soft_reset)
    316 {
    317     ptimer_transaction_begin(s->timer);
    318     /* stop timer */
    319     ptimer_stop(s->timer);
    320 
    321     /* Soft reset and hard reset differ only in their handling of the CR
    322      * register -- soft reset preserves the values of some bits there.
    323      */
    324     if (is_soft_reset) {
    325         /* Clear all CR bits except those that are preserved by soft reset. */
    326         s->cr &= GPT_CR_EN | GPT_CR_ENMOD | GPT_CR_STOPEN | GPT_CR_DOZEN |
    327             GPT_CR_WAITEN | GPT_CR_DBGEN |
    328             (GPT_CR_CLKSRC_MASK << GPT_CR_CLKSRC_SHIFT);
    329     } else {
    330         s->cr = 0;
    331     }
    332     s->sr = 0;
    333     s->pr = 0;
    334     s->ir = 0;
    335     s->cnt = 0;
    336     s->ocr1 = GPT_TIMER_MAX;
    337     s->ocr2 = GPT_TIMER_MAX;
    338     s->ocr3 = GPT_TIMER_MAX;
    339     s->icr1 = 0;
    340     s->icr2 = 0;
    341 
    342     s->next_timeout = GPT_TIMER_MAX;
    343     s->next_int = 0;
    344 
    345     /* compute new freq */
    346     imx_gpt_set_freq(s);
    347 
    348     /* reset the limit to GPT_TIMER_MAX */
    349     ptimer_set_limit(s->timer, GPT_TIMER_MAX, 1);
    350 
    351     /* if the timer is still enabled, restart it */
    352     if (s->freq && (s->cr & GPT_CR_EN)) {
    353         ptimer_run(s->timer, 1);
    354     }
    355     ptimer_transaction_commit(s->timer);
    356 }
    357 
    358 static void imx_gpt_soft_reset(DeviceState *dev)
    359 {
    360     IMXGPTState *s = IMX_GPT(dev);
    361     imx_gpt_reset_common(s, true);
    362 }
    363 
    364 static void imx_gpt_reset(DeviceState *dev)
    365 {
    366     IMXGPTState *s = IMX_GPT(dev);
    367     imx_gpt_reset_common(s, false);
    368 }
    369 
    370 static void imx_gpt_write(void *opaque, hwaddr offset, uint64_t value,
    371                           unsigned size)
    372 {
    373     IMXGPTState *s = IMX_GPT(opaque);
    374     uint32_t oldreg;
    375 
    376     DPRINTF("(%s, value = 0x%08x)\n", imx_gpt_reg_name(offset >> 2),
    377             (uint32_t)value);
    378 
    379     switch (offset >> 2) {
    380     case 0:
    381         oldreg = s->cr;
    382         s->cr = value & ~0x7c14;
    383         if (s->cr & GPT_CR_SWR) { /* force reset */
    384             /* handle the reset */
    385             imx_gpt_soft_reset(DEVICE(s));
    386         } else {
    387             /* set our freq, as the source might have changed */
    388             ptimer_transaction_begin(s->timer);
    389             imx_gpt_set_freq(s);
    390 
    391             if ((oldreg ^ s->cr) & GPT_CR_EN) {
    392                 if (s->cr & GPT_CR_EN) {
    393                     if (s->cr & GPT_CR_ENMOD) {
    394                         s->next_timeout = GPT_TIMER_MAX;
    395                         ptimer_set_count(s->timer, GPT_TIMER_MAX);
    396                         imx_gpt_compute_next_timeout(s, false);
    397                     }
    398                     ptimer_run(s->timer, 1);
    399                 } else {
    400                     /* stop timer */
    401                     ptimer_stop(s->timer);
    402                 }
    403             }
    404             ptimer_transaction_commit(s->timer);
    405         }
    406         break;
    407 
    408     case 1: /* Prescaler */
    409         s->pr = value & 0xfff;
    410         ptimer_transaction_begin(s->timer);
    411         imx_gpt_set_freq(s);
    412         ptimer_transaction_commit(s->timer);
    413         break;
    414 
    415     case 2: /* SR */
    416         s->sr &= ~(value & 0x3f);
    417         imx_gpt_update_int(s);
    418         break;
    419 
    420     case 3: /* IR -- interrupt register */
    421         s->ir = value & 0x3f;
    422         imx_gpt_update_int(s);
    423 
    424         ptimer_transaction_begin(s->timer);
    425         imx_gpt_compute_next_timeout(s, false);
    426         ptimer_transaction_commit(s->timer);
    427 
    428         break;
    429 
    430     case 4: /* OCR1 -- output compare register */
    431         s->ocr1 = value;
    432 
    433         ptimer_transaction_begin(s->timer);
    434         /* In non-freerun mode, reset count when this register is written */
    435         if (!(s->cr & GPT_CR_FRR)) {
    436             s->next_timeout = GPT_TIMER_MAX;
    437             ptimer_set_limit(s->timer, GPT_TIMER_MAX, 1);
    438         }
    439 
    440         /* compute the new timeout */
    441         imx_gpt_compute_next_timeout(s, false);
    442         ptimer_transaction_commit(s->timer);
    443 
    444         break;
    445 
    446     case 5: /* OCR2 -- output compare register */
    447         s->ocr2 = value;
    448 
    449         /* compute the new timeout */
    450         ptimer_transaction_begin(s->timer);
    451         imx_gpt_compute_next_timeout(s, false);
    452         ptimer_transaction_commit(s->timer);
    453 
    454         break;
    455 
    456     case 6: /* OCR3 -- output compare register */
    457         s->ocr3 = value;
    458 
    459         /* compute the new timeout */
    460         ptimer_transaction_begin(s->timer);
    461         imx_gpt_compute_next_timeout(s, false);
    462         ptimer_transaction_commit(s->timer);
    463 
    464         break;
    465 
    466     default:
    467         qemu_log_mask(LOG_GUEST_ERROR, "[%s]%s: Bad register at offset 0x%"
    468                       HWADDR_PRIx "\n", TYPE_IMX_GPT, __func__, offset);
    469         break;
    470     }
    471 }
    472 
    473 static void imx_gpt_timeout(void *opaque)
    474 {
    475     IMXGPTState *s = IMX_GPT(opaque);
    476 
    477     DPRINTF("\n");
    478 
    479     s->sr |= s->next_int;
    480     s->next_int = 0;
    481 
    482     imx_gpt_compute_next_timeout(s, true);
    483 
    484     imx_gpt_update_int(s);
    485 
    486     if (s->freq && (s->cr & GPT_CR_EN)) {
    487         ptimer_run(s->timer, 1);
    488     }
    489 }
    490 
    491 static const MemoryRegionOps imx_gpt_ops = {
    492     .read = imx_gpt_read,
    493     .write = imx_gpt_write,
    494     .endianness = DEVICE_NATIVE_ENDIAN,
    495 };
    496 
    497 
    498 static void imx_gpt_realize(DeviceState *dev, Error **errp)
    499 {
    500     IMXGPTState *s = IMX_GPT(dev);
    501     SysBusDevice *sbd = SYS_BUS_DEVICE(dev);
    502 
    503     sysbus_init_irq(sbd, &s->irq);
    504     memory_region_init_io(&s->iomem, OBJECT(s), &imx_gpt_ops, s, TYPE_IMX_GPT,
    505                           0x00001000);
    506     sysbus_init_mmio(sbd, &s->iomem);
    507 
    508     s->timer = ptimer_init(imx_gpt_timeout, s, PTIMER_POLICY_LEGACY);
    509 }
    510 
    511 static void imx_gpt_class_init(ObjectClass *klass, void *data)
    512 {
    513     DeviceClass *dc = DEVICE_CLASS(klass);
    514 
    515     dc->realize = imx_gpt_realize;
    516     dc->reset = imx_gpt_reset;
    517     dc->vmsd = &vmstate_imx_timer_gpt;
    518     dc->desc = "i.MX general timer";
    519 }
    520 
    521 static void imx25_gpt_init(Object *obj)
    522 {
    523     IMXGPTState *s = IMX_GPT(obj);
    524 
    525     s->clocks = imx25_gpt_clocks;
    526 }
    527 
    528 static void imx31_gpt_init(Object *obj)
    529 {
    530     IMXGPTState *s = IMX_GPT(obj);
    531 
    532     s->clocks = imx31_gpt_clocks;
    533 }
    534 
    535 static void imx6_gpt_init(Object *obj)
    536 {
    537     IMXGPTState *s = IMX_GPT(obj);
    538 
    539     s->clocks = imx6_gpt_clocks;
    540 }
    541 
    542 static void imx7_gpt_init(Object *obj)
    543 {
    544     IMXGPTState *s = IMX_GPT(obj);
    545 
    546     s->clocks = imx7_gpt_clocks;
    547 }
    548 
    549 static const TypeInfo imx25_gpt_info = {
    550     .name = TYPE_IMX25_GPT,
    551     .parent = TYPE_SYS_BUS_DEVICE,
    552     .instance_size = sizeof(IMXGPTState),
    553     .instance_init = imx25_gpt_init,
    554     .class_init = imx_gpt_class_init,
    555 };
    556 
    557 static const TypeInfo imx31_gpt_info = {
    558     .name = TYPE_IMX31_GPT,
    559     .parent = TYPE_IMX25_GPT,
    560     .instance_init = imx31_gpt_init,
    561 };
    562 
    563 static const TypeInfo imx6_gpt_info = {
    564     .name = TYPE_IMX6_GPT,
    565     .parent = TYPE_IMX25_GPT,
    566     .instance_init = imx6_gpt_init,
    567 };
    568 
    569 static const TypeInfo imx7_gpt_info = {
    570     .name = TYPE_IMX7_GPT,
    571     .parent = TYPE_IMX25_GPT,
    572     .instance_init = imx7_gpt_init,
    573 };
    574 
    575 static void imx_gpt_register_types(void)
    576 {
    577     type_register_static(&imx25_gpt_info);
    578     type_register_static(&imx31_gpt_info);
    579     type_register_static(&imx6_gpt_info);
    580     type_register_static(&imx7_gpt_info);
    581 }
    582 
    583 type_init(imx_gpt_register_types)