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