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 "hw/irq.h" 18 #include "hw/misc/imx_ccm.h" 19 #include "qemu/main-loop.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 35 static 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 */ 57 static 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 */ 67 static 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 static void imx_epit_set_freq(IMXEPITState *s) 77 { 78 uint32_t clksrc; 79 uint32_t prescaler; 80 81 clksrc = extract32(s->cr, CR_CLKSRC_SHIFT, 2); 82 prescaler = 1 + extract32(s->cr, CR_PRESCALE_SHIFT, 12); 83 84 s->freq = imx_ccm_get_clock_frequency(s->ccm, 85 imx_epit_clocks[clksrc]) / prescaler; 86 87 DPRINTF("Setting ptimer frequency to %u\n", s->freq); 88 89 if (s->freq) { 90 ptimer_set_freq(s->timer_reload, s->freq); 91 ptimer_set_freq(s->timer_cmp, s->freq); 92 } 93 } 94 95 static void imx_epit_reset(DeviceState *dev) 96 { 97 IMXEPITState *s = IMX_EPIT(dev); 98 99 /* 100 * Soft reset doesn't touch some bits; hard reset clears them 101 */ 102 s->cr &= (CR_EN|CR_ENMOD|CR_STOPEN|CR_DOZEN|CR_WAITEN|CR_DBGEN); 103 s->sr = 0; 104 s->lr = EPIT_TIMER_MAX; 105 s->cmp = 0; 106 s->cnt = 0; 107 /* stop both timers */ 108 ptimer_stop(s->timer_cmp); 109 ptimer_stop(s->timer_reload); 110 /* compute new frequency */ 111 imx_epit_set_freq(s); 112 /* init both timers to EPIT_TIMER_MAX */ 113 ptimer_set_limit(s->timer_cmp, EPIT_TIMER_MAX, 1); 114 ptimer_set_limit(s->timer_reload, EPIT_TIMER_MAX, 1); 115 if (s->freq && (s->cr & CR_EN)) { 116 /* if the timer is still enabled, restart it */ 117 ptimer_run(s->timer_reload, 0); 118 } 119 } 120 121 static uint32_t imx_epit_update_count(IMXEPITState *s) 122 { 123 s->cnt = ptimer_get_count(s->timer_reload); 124 125 return s->cnt; 126 } 127 128 static uint64_t imx_epit_read(void *opaque, hwaddr offset, unsigned size) 129 { 130 IMXEPITState *s = IMX_EPIT(opaque); 131 uint32_t reg_value = 0; 132 133 switch (offset >> 2) { 134 case 0: /* Control Register */ 135 reg_value = s->cr; 136 break; 137 138 case 1: /* Status Register */ 139 reg_value = s->sr; 140 break; 141 142 case 2: /* LR - ticks*/ 143 reg_value = s->lr; 144 break; 145 146 case 3: /* CMP */ 147 reg_value = s->cmp; 148 break; 149 150 case 4: /* CNT */ 151 imx_epit_update_count(s); 152 reg_value = s->cnt; 153 break; 154 155 default: 156 qemu_log_mask(LOG_GUEST_ERROR, "[%s]%s: Bad register at offset 0x%" 157 HWADDR_PRIx "\n", TYPE_IMX_EPIT, __func__, offset); 158 break; 159 } 160 161 DPRINTF("(%s) = 0x%08x\n", imx_epit_reg_name(offset >> 2), reg_value); 162 163 return reg_value; 164 } 165 166 static void imx_epit_reload_compare_timer(IMXEPITState *s) 167 { 168 if ((s->cr & (CR_EN | CR_OCIEN)) == (CR_EN | CR_OCIEN)) { 169 /* if the compare feature is on and timers are running */ 170 uint32_t tmp = imx_epit_update_count(s); 171 uint64_t next; 172 if (tmp > s->cmp) { 173 /* It'll fire in this round of the timer */ 174 next = tmp - s->cmp; 175 } else { /* catch it next time around */ 176 next = tmp - s->cmp + ((s->cr & CR_RLD) ? EPIT_TIMER_MAX : s->lr); 177 } 178 ptimer_set_count(s->timer_cmp, next); 179 } 180 } 181 182 static void imx_epit_write(void *opaque, hwaddr offset, uint64_t value, 183 unsigned size) 184 { 185 IMXEPITState *s = IMX_EPIT(opaque); 186 uint64_t oldcr; 187 188 DPRINTF("(%s, value = 0x%08x)\n", imx_epit_reg_name(offset >> 2), 189 (uint32_t)value); 190 191 switch (offset >> 2) { 192 case 0: /* CR */ 193 194 oldcr = s->cr; 195 s->cr = value & 0x03ffffff; 196 if (s->cr & CR_SWR) { 197 /* handle the reset */ 198 imx_epit_reset(DEVICE(s)); 199 } else { 200 imx_epit_set_freq(s); 201 } 202 203 if (s->freq && (s->cr & CR_EN) && !(oldcr & CR_EN)) { 204 if (s->cr & CR_ENMOD) { 205 if (s->cr & CR_RLD) { 206 ptimer_set_limit(s->timer_reload, s->lr, 1); 207 ptimer_set_limit(s->timer_cmp, s->lr, 1); 208 } else { 209 ptimer_set_limit(s->timer_reload, EPIT_TIMER_MAX, 1); 210 ptimer_set_limit(s->timer_cmp, EPIT_TIMER_MAX, 1); 211 } 212 } 213 214 imx_epit_reload_compare_timer(s); 215 ptimer_run(s->timer_reload, 0); 216 if (s->cr & CR_OCIEN) { 217 ptimer_run(s->timer_cmp, 0); 218 } else { 219 ptimer_stop(s->timer_cmp); 220 } 221 } else if (!(s->cr & CR_EN)) { 222 /* stop both timers */ 223 ptimer_stop(s->timer_reload); 224 ptimer_stop(s->timer_cmp); 225 } else if (s->cr & CR_OCIEN) { 226 if (!(oldcr & CR_OCIEN)) { 227 imx_epit_reload_compare_timer(s); 228 ptimer_run(s->timer_cmp, 0); 229 } 230 } else { 231 ptimer_stop(s->timer_cmp); 232 } 233 break; 234 235 case 1: /* SR - ACK*/ 236 /* writing 1 to OCIF clear the OCIF bit */ 237 if (value & 0x01) { 238 s->sr = 0; 239 imx_epit_update_int(s); 240 } 241 break; 242 243 case 2: /* LR - set ticks */ 244 s->lr = value; 245 246 if (s->cr & CR_RLD) { 247 /* Also set the limit if the LRD bit is set */ 248 /* If IOVW bit is set then set the timer value */ 249 ptimer_set_limit(s->timer_reload, s->lr, s->cr & CR_IOVW); 250 ptimer_set_limit(s->timer_cmp, s->lr, 0); 251 } else if (s->cr & CR_IOVW) { 252 /* If IOVW bit is set then set the timer value */ 253 ptimer_set_count(s->timer_reload, s->lr); 254 } 255 256 imx_epit_reload_compare_timer(s); 257 break; 258 259 case 3: /* CMP */ 260 s->cmp = value; 261 262 imx_epit_reload_compare_timer(s); 263 264 break; 265 266 default: 267 qemu_log_mask(LOG_GUEST_ERROR, "[%s]%s: Bad register at offset 0x%" 268 HWADDR_PRIx "\n", TYPE_IMX_EPIT, __func__, offset); 269 270 break; 271 } 272 } 273 static void imx_epit_cmp(void *opaque) 274 { 275 IMXEPITState *s = IMX_EPIT(opaque); 276 277 DPRINTF("sr was %d\n", s->sr); 278 279 s->sr = 1; 280 imx_epit_update_int(s); 281 } 282 283 static const MemoryRegionOps imx_epit_ops = { 284 .read = imx_epit_read, 285 .write = imx_epit_write, 286 .endianness = DEVICE_NATIVE_ENDIAN, 287 }; 288 289 static const VMStateDescription vmstate_imx_timer_epit = { 290 .name = TYPE_IMX_EPIT, 291 .version_id = 2, 292 .minimum_version_id = 2, 293 .fields = (VMStateField[]) { 294 VMSTATE_UINT32(cr, IMXEPITState), 295 VMSTATE_UINT32(sr, IMXEPITState), 296 VMSTATE_UINT32(lr, IMXEPITState), 297 VMSTATE_UINT32(cmp, IMXEPITState), 298 VMSTATE_UINT32(cnt, IMXEPITState), 299 VMSTATE_UINT32(freq, IMXEPITState), 300 VMSTATE_PTIMER(timer_reload, IMXEPITState), 301 VMSTATE_PTIMER(timer_cmp, IMXEPITState), 302 VMSTATE_END_OF_LIST() 303 } 304 }; 305 306 static void imx_epit_realize(DeviceState *dev, Error **errp) 307 { 308 IMXEPITState *s = IMX_EPIT(dev); 309 SysBusDevice *sbd = SYS_BUS_DEVICE(dev); 310 QEMUBH *bh; 311 312 DPRINTF("\n"); 313 314 sysbus_init_irq(sbd, &s->irq); 315 memory_region_init_io(&s->iomem, OBJECT(s), &imx_epit_ops, s, TYPE_IMX_EPIT, 316 0x00001000); 317 sysbus_init_mmio(sbd, &s->iomem); 318 319 s->timer_reload = ptimer_init(NULL, PTIMER_POLICY_DEFAULT); 320 321 bh = qemu_bh_new(imx_epit_cmp, s); 322 s->timer_cmp = ptimer_init(bh, PTIMER_POLICY_DEFAULT); 323 } 324 325 static void imx_epit_class_init(ObjectClass *klass, void *data) 326 { 327 DeviceClass *dc = DEVICE_CLASS(klass); 328 329 dc->realize = imx_epit_realize; 330 dc->reset = imx_epit_reset; 331 dc->vmsd = &vmstate_imx_timer_epit; 332 dc->desc = "i.MX periodic timer"; 333 } 334 335 static const TypeInfo imx_epit_info = { 336 .name = TYPE_IMX_EPIT, 337 .parent = TYPE_SYS_BUS_DEVICE, 338 .instance_size = sizeof(IMXEPITState), 339 .class_init = imx_epit_class_init, 340 }; 341 342 static void imx_epit_register_types(void) 343 { 344 type_register_static(&imx_epit_info); 345 } 346 347 type_init(imx_epit_register_types) 348