qemu/hw/timer/imx_gpt.c
<<
>>
Prefs
   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
  30static 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
 119typedef 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
 144static 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
 168static 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
 179static 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
 193static 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
 202static 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
 209static 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
 219static 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
 297static 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
 357static 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
 394static 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
 485static 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
 503static const MemoryRegionOps imx_gpt_ops = {
 504    .read = imx_gpt_read,
 505    .write = imx_gpt_write,
 506    .endianness = DEVICE_NATIVE_ENDIAN,
 507};
 508
 509
 510static 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
 525void 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
 535static 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
 545static 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
 552static void imx_gpt_register_types(void)
 553{
 554    type_register_static(&imx_gpt_info);
 555}
 556
 557type_init(imx_gpt_register_types)
 558