qemu/hw/timer/imx_epit.c
<<
>>
Prefs
   1/*
   2 * IMX EPIT 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/timer/imx_epit.h"
  17#include "migration/vmstate.h"
  18#include "hw/irq.h"
  19#include "hw/misc/imx_ccm.h"
  20#include "qemu/module.h"
  21#include "qemu/log.h"
  22
  23#ifndef DEBUG_IMX_EPIT
  24#define DEBUG_IMX_EPIT 0
  25#endif
  26
  27#define DPRINTF(fmt, args...) \
  28    do { \
  29        if (DEBUG_IMX_EPIT) { \
  30            fprintf(stderr, "[%s]%s: " fmt , TYPE_IMX_EPIT, \
  31                                             __func__, ##args); \
  32        } \
  33    } while (0)
  34
  35static const char *imx_epit_reg_name(uint32_t reg)
  36{
  37    switch (reg) {
  38    case 0:
  39        return "CR";
  40    case 1:
  41        return "SR";
  42    case 2:
  43        return "LR";
  44    case 3:
  45        return "CMP";
  46    case 4:
  47        return "CNT";
  48    default:
  49        return "[?]";
  50    }
  51}
  52
  53/*
  54 * Exact clock frequencies vary from board to board.
  55 * These are typical.
  56 */
  57static const IMXClk imx_epit_clocks[] =  {
  58    CLK_NONE,      /* 00 disabled */
  59    CLK_IPG,       /* 01 ipg_clk, ~532MHz */
  60    CLK_IPG_HIGH,  /* 10 ipg_clk_highfreq */
  61    CLK_32k,       /* 11 ipg_clk_32k -- ~32kHz */
  62};
  63
  64/*
  65 * Update interrupt status
  66 */
  67static void imx_epit_update_int(IMXEPITState *s)
  68{
  69    if (s->sr && (s->cr & CR_OCIEN) && (s->cr & CR_EN)) {
  70        qemu_irq_raise(s->irq);
  71    } else {
  72        qemu_irq_lower(s->irq);
  73    }
  74}
  75
  76/*
  77 * Must be called from within a ptimer_transaction_begin/commit block
  78 * for both s->timer_cmp and s->timer_reload.
  79 */
  80static void imx_epit_set_freq(IMXEPITState *s)
  81{
  82    uint32_t clksrc;
  83    uint32_t prescaler;
  84
  85    clksrc = extract32(s->cr, CR_CLKSRC_SHIFT, 2);
  86    prescaler = 1 + extract32(s->cr, CR_PRESCALE_SHIFT, 12);
  87
  88    s->freq = imx_ccm_get_clock_frequency(s->ccm,
  89                                imx_epit_clocks[clksrc]) / prescaler;
  90
  91    DPRINTF("Setting ptimer frequency to %u\n", s->freq);
  92
  93    if (s->freq) {
  94        ptimer_set_freq(s->timer_reload, s->freq);
  95        ptimer_set_freq(s->timer_cmp, s->freq);
  96    }
  97}
  98
  99static void imx_epit_reset(DeviceState *dev)
 100{
 101    IMXEPITState *s = IMX_EPIT(dev);
 102
 103    /*
 104     * Soft reset doesn't touch some bits; hard reset clears them
 105     */
 106    s->cr &= (CR_EN|CR_ENMOD|CR_STOPEN|CR_DOZEN|CR_WAITEN|CR_DBGEN);
 107    s->sr = 0;
 108    s->lr = EPIT_TIMER_MAX;
 109    s->cmp = 0;
 110    s->cnt = 0;
 111    ptimer_transaction_begin(s->timer_cmp);
 112    ptimer_transaction_begin(s->timer_reload);
 113    /* stop both timers */
 114    ptimer_stop(s->timer_cmp);
 115    ptimer_stop(s->timer_reload);
 116    /* compute new frequency */
 117    imx_epit_set_freq(s);
 118    /* init both timers to EPIT_TIMER_MAX */
 119    ptimer_set_limit(s->timer_cmp, EPIT_TIMER_MAX, 1);
 120    ptimer_set_limit(s->timer_reload, EPIT_TIMER_MAX, 1);
 121    if (s->freq && (s->cr & CR_EN)) {
 122        /* if the timer is still enabled, restart it */
 123        ptimer_run(s->timer_reload, 0);
 124    }
 125    ptimer_transaction_commit(s->timer_cmp);
 126    ptimer_transaction_commit(s->timer_reload);
 127}
 128
 129static uint32_t imx_epit_update_count(IMXEPITState *s)
 130{
 131    s->cnt = ptimer_get_count(s->timer_reload);
 132
 133    return s->cnt;
 134}
 135
 136static uint64_t imx_epit_read(void *opaque, hwaddr offset, unsigned size)
 137{
 138    IMXEPITState *s = IMX_EPIT(opaque);
 139    uint32_t reg_value = 0;
 140
 141    switch (offset >> 2) {
 142    case 0: /* Control Register */
 143        reg_value = s->cr;
 144        break;
 145
 146    case 1: /* Status Register */
 147        reg_value = s->sr;
 148        break;
 149
 150    case 2: /* LR - ticks*/
 151        reg_value = s->lr;
 152        break;
 153
 154    case 3: /* CMP */
 155        reg_value = s->cmp;
 156        break;
 157
 158    case 4: /* CNT */
 159        imx_epit_update_count(s);
 160        reg_value = s->cnt;
 161        break;
 162
 163    default:
 164        qemu_log_mask(LOG_GUEST_ERROR, "[%s]%s: Bad register at offset 0x%"
 165                      HWADDR_PRIx "\n", TYPE_IMX_EPIT, __func__, offset);
 166        break;
 167    }
 168
 169    DPRINTF("(%s) = 0x%08x\n", imx_epit_reg_name(offset >> 2), reg_value);
 170
 171    return reg_value;
 172}
 173
 174/* Must be called from ptimer_transaction_begin/commit block for s->timer_cmp */
 175static void imx_epit_reload_compare_timer(IMXEPITState *s)
 176{
 177    if ((s->cr & (CR_EN | CR_OCIEN)) == (CR_EN | CR_OCIEN))  {
 178        /* if the compare feature is on and timers are running */
 179        uint32_t tmp = imx_epit_update_count(s);
 180        uint64_t next;
 181        if (tmp > s->cmp) {
 182            /* It'll fire in this round of the timer */
 183            next = tmp - s->cmp;
 184        } else { /* catch it next time around */
 185            next = tmp - s->cmp + ((s->cr & CR_RLD) ? EPIT_TIMER_MAX : s->lr);
 186        }
 187        ptimer_set_count(s->timer_cmp, next);
 188    }
 189}
 190
 191static void imx_epit_write(void *opaque, hwaddr offset, uint64_t value,
 192                           unsigned size)
 193{
 194    IMXEPITState *s = IMX_EPIT(opaque);
 195    uint64_t oldcr;
 196
 197    DPRINTF("(%s, value = 0x%08x)\n", imx_epit_reg_name(offset >> 2),
 198            (uint32_t)value);
 199
 200    switch (offset >> 2) {
 201    case 0: /* CR */
 202
 203        oldcr = s->cr;
 204        s->cr = value & 0x03ffffff;
 205        if (s->cr & CR_SWR) {
 206            /* handle the reset */
 207            imx_epit_reset(DEVICE(s));
 208            /*
 209             * TODO: could we 'break' here? following operations appear
 210             * to duplicate the work imx_epit_reset() already did.
 211             */
 212        }
 213
 214        ptimer_transaction_begin(s->timer_cmp);
 215        ptimer_transaction_begin(s->timer_reload);
 216
 217        if (!(s->cr & CR_SWR)) {
 218            imx_epit_set_freq(s);
 219        }
 220
 221        if (s->freq && (s->cr & CR_EN) && !(oldcr & CR_EN)) {
 222            if (s->cr & CR_ENMOD) {
 223                if (s->cr & CR_RLD) {
 224                    ptimer_set_limit(s->timer_reload, s->lr, 1);
 225                    ptimer_set_limit(s->timer_cmp, s->lr, 1);
 226                } else {
 227                    ptimer_set_limit(s->timer_reload, EPIT_TIMER_MAX, 1);
 228                    ptimer_set_limit(s->timer_cmp, EPIT_TIMER_MAX, 1);
 229                }
 230            }
 231
 232            imx_epit_reload_compare_timer(s);
 233            ptimer_run(s->timer_reload, 0);
 234            if (s->cr & CR_OCIEN) {
 235                ptimer_run(s->timer_cmp, 0);
 236            } else {
 237                ptimer_stop(s->timer_cmp);
 238            }
 239        } else if (!(s->cr & CR_EN)) {
 240            /* stop both timers */
 241            ptimer_stop(s->timer_reload);
 242            ptimer_stop(s->timer_cmp);
 243        } else  if (s->cr & CR_OCIEN) {
 244            if (!(oldcr & CR_OCIEN)) {
 245                imx_epit_reload_compare_timer(s);
 246                ptimer_run(s->timer_cmp, 0);
 247            }
 248        } else {
 249            ptimer_stop(s->timer_cmp);
 250        }
 251
 252        ptimer_transaction_commit(s->timer_cmp);
 253        ptimer_transaction_commit(s->timer_reload);
 254        break;
 255
 256    case 1: /* SR - ACK*/
 257        /* writing 1 to OCIF clear the OCIF bit */
 258        if (value & 0x01) {
 259            s->sr = 0;
 260            imx_epit_update_int(s);
 261        }
 262        break;
 263
 264    case 2: /* LR - set ticks */
 265        s->lr = value;
 266
 267        ptimer_transaction_begin(s->timer_cmp);
 268        ptimer_transaction_begin(s->timer_reload);
 269        if (s->cr & CR_RLD) {
 270            /* Also set the limit if the LRD bit is set */
 271            /* If IOVW bit is set then set the timer value */
 272            ptimer_set_limit(s->timer_reload, s->lr, s->cr & CR_IOVW);
 273            ptimer_set_limit(s->timer_cmp, s->lr, 0);
 274        } else if (s->cr & CR_IOVW) {
 275            /* If IOVW bit is set then set the timer value */
 276            ptimer_set_count(s->timer_reload, s->lr);
 277        }
 278
 279        imx_epit_reload_compare_timer(s);
 280        ptimer_transaction_commit(s->timer_cmp);
 281        ptimer_transaction_commit(s->timer_reload);
 282        break;
 283
 284    case 3: /* CMP */
 285        s->cmp = value;
 286
 287        ptimer_transaction_begin(s->timer_cmp);
 288        imx_epit_reload_compare_timer(s);
 289        ptimer_transaction_commit(s->timer_cmp);
 290
 291        break;
 292
 293    default:
 294        qemu_log_mask(LOG_GUEST_ERROR, "[%s]%s: Bad register at offset 0x%"
 295                      HWADDR_PRIx "\n", TYPE_IMX_EPIT, __func__, offset);
 296
 297        break;
 298    }
 299}
 300static void imx_epit_cmp(void *opaque)
 301{
 302    IMXEPITState *s = IMX_EPIT(opaque);
 303
 304    DPRINTF("sr was %d\n", s->sr);
 305
 306    s->sr = 1;
 307    imx_epit_update_int(s);
 308}
 309
 310static void imx_epit_reload(void *opaque)
 311{
 312    /* No action required on rollover of timer_reload */
 313}
 314
 315static const MemoryRegionOps imx_epit_ops = {
 316    .read = imx_epit_read,
 317    .write = imx_epit_write,
 318    .endianness = DEVICE_NATIVE_ENDIAN,
 319};
 320
 321static const VMStateDescription vmstate_imx_timer_epit = {
 322    .name = TYPE_IMX_EPIT,
 323    .version_id = 2,
 324    .minimum_version_id = 2,
 325    .fields = (VMStateField[]) {
 326        VMSTATE_UINT32(cr, IMXEPITState),
 327        VMSTATE_UINT32(sr, IMXEPITState),
 328        VMSTATE_UINT32(lr, IMXEPITState),
 329        VMSTATE_UINT32(cmp, IMXEPITState),
 330        VMSTATE_UINT32(cnt, IMXEPITState),
 331        VMSTATE_UINT32(freq, IMXEPITState),
 332        VMSTATE_PTIMER(timer_reload, IMXEPITState),
 333        VMSTATE_PTIMER(timer_cmp, IMXEPITState),
 334        VMSTATE_END_OF_LIST()
 335    }
 336};
 337
 338static void imx_epit_realize(DeviceState *dev, Error **errp)
 339{
 340    IMXEPITState *s = IMX_EPIT(dev);
 341    SysBusDevice *sbd = SYS_BUS_DEVICE(dev);
 342
 343    DPRINTF("\n");
 344
 345    sysbus_init_irq(sbd, &s->irq);
 346    memory_region_init_io(&s->iomem, OBJECT(s), &imx_epit_ops, s, TYPE_IMX_EPIT,
 347                          0x00001000);
 348    sysbus_init_mmio(sbd, &s->iomem);
 349
 350    s->timer_reload = ptimer_init(imx_epit_reload, s, PTIMER_POLICY_DEFAULT);
 351
 352    s->timer_cmp = ptimer_init(imx_epit_cmp, s, PTIMER_POLICY_DEFAULT);
 353}
 354
 355static void imx_epit_class_init(ObjectClass *klass, void *data)
 356{
 357    DeviceClass *dc  = DEVICE_CLASS(klass);
 358
 359    dc->realize = imx_epit_realize;
 360    dc->reset = imx_epit_reset;
 361    dc->vmsd = &vmstate_imx_timer_epit;
 362    dc->desc = "i.MX periodic timer";
 363}
 364
 365static const TypeInfo imx_epit_info = {
 366    .name = TYPE_IMX_EPIT,
 367    .parent = TYPE_SYS_BUS_DEVICE,
 368    .instance_size = sizeof(IMXEPITState),
 369    .class_init = imx_epit_class_init,
 370};
 371
 372static void imx_epit_register_types(void)
 373{
 374    type_register_static(&imx_epit_info);
 375}
 376
 377type_init(imx_epit_register_types)
 378