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