imx_epit.c (10326B)
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)