1 /* 2 * Intel XScale PXA255/270 OS Timers. 3 * 4 * Copyright (c) 2006 Openedhand Ltd. 5 * Copyright (c) 2006 Thorsten Zitterell 6 * 7 * This code is licensed under the GPL. 8 */ 9 10 #include "qemu/osdep.h" 11 #include "hw/hw.h" 12 #include "qemu/timer.h" 13 #include "sysemu/sysemu.h" 14 #include "hw/arm/pxa.h" 15 #include "hw/sysbus.h" 16 17 #define OSMR0 0x00 18 #define OSMR1 0x04 19 #define OSMR2 0x08 20 #define OSMR3 0x0c 21 #define OSMR4 0x80 22 #define OSMR5 0x84 23 #define OSMR6 0x88 24 #define OSMR7 0x8c 25 #define OSMR8 0x90 26 #define OSMR9 0x94 27 #define OSMR10 0x98 28 #define OSMR11 0x9c 29 #define OSCR 0x10 /* OS Timer Count */ 30 #define OSCR4 0x40 31 #define OSCR5 0x44 32 #define OSCR6 0x48 33 #define OSCR7 0x4c 34 #define OSCR8 0x50 35 #define OSCR9 0x54 36 #define OSCR10 0x58 37 #define OSCR11 0x5c 38 #define OSSR 0x14 /* Timer status register */ 39 #define OWER 0x18 40 #define OIER 0x1c /* Interrupt enable register 3-0 to E3-E0 */ 41 #define OMCR4 0xc0 /* OS Match Control registers */ 42 #define OMCR5 0xc4 43 #define OMCR6 0xc8 44 #define OMCR7 0xcc 45 #define OMCR8 0xd0 46 #define OMCR9 0xd4 47 #define OMCR10 0xd8 48 #define OMCR11 0xdc 49 #define OSNR 0x20 50 51 #define PXA25X_FREQ 3686400 /* 3.6864 MHz */ 52 #define PXA27X_FREQ 3250000 /* 3.25 MHz */ 53 54 static int pxa2xx_timer4_freq[8] = { 55 [0] = 0, 56 [1] = 32768, 57 [2] = 1000, 58 [3] = 1, 59 [4] = 1000000, 60 /* [5] is the "Externally supplied clock". Assign if necessary. */ 61 [5 ... 7] = 0, 62 }; 63 64 #define TYPE_PXA2XX_TIMER "pxa2xx-timer" 65 #define PXA2XX_TIMER(obj) \ 66 OBJECT_CHECK(PXA2xxTimerInfo, (obj), TYPE_PXA2XX_TIMER) 67 68 typedef struct PXA2xxTimerInfo PXA2xxTimerInfo; 69 70 typedef struct { 71 uint32_t value; 72 qemu_irq irq; 73 QEMUTimer *qtimer; 74 int num; 75 PXA2xxTimerInfo *info; 76 } PXA2xxTimer0; 77 78 typedef struct { 79 PXA2xxTimer0 tm; 80 int32_t oldclock; 81 int32_t clock; 82 uint64_t lastload; 83 uint32_t freq; 84 uint32_t control; 85 } PXA2xxTimer4; 86 87 struct PXA2xxTimerInfo { 88 SysBusDevice parent_obj; 89 90 MemoryRegion iomem; 91 uint32_t flags; 92 93 int32_t clock; 94 int32_t oldclock; 95 uint64_t lastload; 96 uint32_t freq; 97 PXA2xxTimer0 timer[4]; 98 uint32_t events; 99 uint32_t irq_enabled; 100 uint32_t reset3; 101 uint32_t snapshot; 102 103 qemu_irq irq4; 104 PXA2xxTimer4 tm4[8]; 105 }; 106 107 #define PXA2XX_TIMER_HAVE_TM4 0 108 109 static inline int pxa2xx_timer_has_tm4(PXA2xxTimerInfo *s) 110 { 111 return s->flags & (1 << PXA2XX_TIMER_HAVE_TM4); 112 } 113 114 static void pxa2xx_timer_update(void *opaque, uint64_t now_qemu) 115 { 116 PXA2xxTimerInfo *s = (PXA2xxTimerInfo *) opaque; 117 int i; 118 uint32_t now_vm; 119 uint64_t new_qemu; 120 121 now_vm = s->clock + 122 muldiv64(now_qemu - s->lastload, s->freq, get_ticks_per_sec()); 123 124 for (i = 0; i < 4; i ++) { 125 new_qemu = now_qemu + muldiv64((uint32_t) (s->timer[i].value - now_vm), 126 get_ticks_per_sec(), s->freq); 127 timer_mod(s->timer[i].qtimer, new_qemu); 128 } 129 } 130 131 static void pxa2xx_timer_update4(void *opaque, uint64_t now_qemu, int n) 132 { 133 PXA2xxTimerInfo *s = (PXA2xxTimerInfo *) opaque; 134 uint32_t now_vm; 135 uint64_t new_qemu; 136 static const int counters[8] = { 0, 0, 0, 0, 4, 4, 6, 6 }; 137 int counter; 138 139 if (s->tm4[n].control & (1 << 7)) 140 counter = n; 141 else 142 counter = counters[n]; 143 144 if (!s->tm4[counter].freq) { 145 timer_del(s->tm4[n].tm.qtimer); 146 return; 147 } 148 149 now_vm = s->tm4[counter].clock + muldiv64(now_qemu - 150 s->tm4[counter].lastload, 151 s->tm4[counter].freq, get_ticks_per_sec()); 152 153 new_qemu = now_qemu + muldiv64((uint32_t) (s->tm4[n].tm.value - now_vm), 154 get_ticks_per_sec(), s->tm4[counter].freq); 155 timer_mod(s->tm4[n].tm.qtimer, new_qemu); 156 } 157 158 static uint64_t pxa2xx_timer_read(void *opaque, hwaddr offset, 159 unsigned size) 160 { 161 PXA2xxTimerInfo *s = (PXA2xxTimerInfo *) opaque; 162 int tm = 0; 163 164 switch (offset) { 165 case OSMR3: tm ++; 166 /* fall through */ 167 case OSMR2: tm ++; 168 /* fall through */ 169 case OSMR1: tm ++; 170 /* fall through */ 171 case OSMR0: 172 return s->timer[tm].value; 173 case OSMR11: tm ++; 174 /* fall through */ 175 case OSMR10: tm ++; 176 /* fall through */ 177 case OSMR9: tm ++; 178 /* fall through */ 179 case OSMR8: tm ++; 180 /* fall through */ 181 case OSMR7: tm ++; 182 /* fall through */ 183 case OSMR6: tm ++; 184 /* fall through */ 185 case OSMR5: tm ++; 186 /* fall through */ 187 case OSMR4: 188 if (!pxa2xx_timer_has_tm4(s)) 189 goto badreg; 190 return s->tm4[tm].tm.value; 191 case OSCR: 192 return s->clock + muldiv64(qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL) - 193 s->lastload, s->freq, get_ticks_per_sec()); 194 case OSCR11: tm ++; 195 /* fall through */ 196 case OSCR10: tm ++; 197 /* fall through */ 198 case OSCR9: tm ++; 199 /* fall through */ 200 case OSCR8: tm ++; 201 /* fall through */ 202 case OSCR7: tm ++; 203 /* fall through */ 204 case OSCR6: tm ++; 205 /* fall through */ 206 case OSCR5: tm ++; 207 /* fall through */ 208 case OSCR4: 209 if (!pxa2xx_timer_has_tm4(s)) 210 goto badreg; 211 212 if ((tm == 9 - 4 || tm == 11 - 4) && (s->tm4[tm].control & (1 << 9))) { 213 if (s->tm4[tm - 1].freq) 214 s->snapshot = s->tm4[tm - 1].clock + muldiv64( 215 qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL) - 216 s->tm4[tm - 1].lastload, 217 s->tm4[tm - 1].freq, get_ticks_per_sec()); 218 else 219 s->snapshot = s->tm4[tm - 1].clock; 220 } 221 222 if (!s->tm4[tm].freq) 223 return s->tm4[tm].clock; 224 return s->tm4[tm].clock + muldiv64(qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL) - 225 s->tm4[tm].lastload, s->tm4[tm].freq, get_ticks_per_sec()); 226 case OIER: 227 return s->irq_enabled; 228 case OSSR: /* Status register */ 229 return s->events; 230 case OWER: 231 return s->reset3; 232 case OMCR11: tm ++; 233 /* fall through */ 234 case OMCR10: tm ++; 235 /* fall through */ 236 case OMCR9: tm ++; 237 /* fall through */ 238 case OMCR8: tm ++; 239 /* fall through */ 240 case OMCR7: tm ++; 241 /* fall through */ 242 case OMCR6: tm ++; 243 /* fall through */ 244 case OMCR5: tm ++; 245 /* fall through */ 246 case OMCR4: 247 if (!pxa2xx_timer_has_tm4(s)) 248 goto badreg; 249 return s->tm4[tm].control; 250 case OSNR: 251 return s->snapshot; 252 default: 253 badreg: 254 hw_error("pxa2xx_timer_read: Bad offset " REG_FMT "\n", offset); 255 } 256 257 return 0; 258 } 259 260 static void pxa2xx_timer_write(void *opaque, hwaddr offset, 261 uint64_t value, unsigned size) 262 { 263 int i, tm = 0; 264 PXA2xxTimerInfo *s = (PXA2xxTimerInfo *) opaque; 265 266 switch (offset) { 267 case OSMR3: tm ++; 268 /* fall through */ 269 case OSMR2: tm ++; 270 /* fall through */ 271 case OSMR1: tm ++; 272 /* fall through */ 273 case OSMR0: 274 s->timer[tm].value = value; 275 pxa2xx_timer_update(s, qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL)); 276 break; 277 case OSMR11: tm ++; 278 /* fall through */ 279 case OSMR10: tm ++; 280 /* fall through */ 281 case OSMR9: tm ++; 282 /* fall through */ 283 case OSMR8: tm ++; 284 /* fall through */ 285 case OSMR7: tm ++; 286 /* fall through */ 287 case OSMR6: tm ++; 288 /* fall through */ 289 case OSMR5: tm ++; 290 /* fall through */ 291 case OSMR4: 292 if (!pxa2xx_timer_has_tm4(s)) 293 goto badreg; 294 s->tm4[tm].tm.value = value; 295 pxa2xx_timer_update4(s, qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL), tm); 296 break; 297 case OSCR: 298 s->oldclock = s->clock; 299 s->lastload = qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL); 300 s->clock = value; 301 pxa2xx_timer_update(s, s->lastload); 302 break; 303 case OSCR11: tm ++; 304 /* fall through */ 305 case OSCR10: tm ++; 306 /* fall through */ 307 case OSCR9: tm ++; 308 /* fall through */ 309 case OSCR8: tm ++; 310 /* fall through */ 311 case OSCR7: tm ++; 312 /* fall through */ 313 case OSCR6: tm ++; 314 /* fall through */ 315 case OSCR5: tm ++; 316 /* fall through */ 317 case OSCR4: 318 if (!pxa2xx_timer_has_tm4(s)) 319 goto badreg; 320 s->tm4[tm].oldclock = s->tm4[tm].clock; 321 s->tm4[tm].lastload = qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL); 322 s->tm4[tm].clock = value; 323 pxa2xx_timer_update4(s, s->tm4[tm].lastload, tm); 324 break; 325 case OIER: 326 s->irq_enabled = value & 0xfff; 327 break; 328 case OSSR: /* Status register */ 329 value &= s->events; 330 s->events &= ~value; 331 for (i = 0; i < 4; i ++, value >>= 1) 332 if (value & 1) 333 qemu_irq_lower(s->timer[i].irq); 334 if (pxa2xx_timer_has_tm4(s) && !(s->events & 0xff0) && value) 335 qemu_irq_lower(s->irq4); 336 break; 337 case OWER: /* XXX: Reset on OSMR3 match? */ 338 s->reset3 = value; 339 break; 340 case OMCR7: tm ++; 341 /* fall through */ 342 case OMCR6: tm ++; 343 /* fall through */ 344 case OMCR5: tm ++; 345 /* fall through */ 346 case OMCR4: 347 if (!pxa2xx_timer_has_tm4(s)) 348 goto badreg; 349 s->tm4[tm].control = value & 0x0ff; 350 /* XXX Stop if running (shouldn't happen) */ 351 if ((value & (1 << 7)) || tm == 0) 352 s->tm4[tm].freq = pxa2xx_timer4_freq[value & 7]; 353 else { 354 s->tm4[tm].freq = 0; 355 pxa2xx_timer_update4(s, qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL), tm); 356 } 357 break; 358 case OMCR11: tm ++; 359 /* fall through */ 360 case OMCR10: tm ++; 361 /* fall through */ 362 case OMCR9: tm ++; 363 /* fall through */ 364 case OMCR8: tm += 4; 365 if (!pxa2xx_timer_has_tm4(s)) 366 goto badreg; 367 s->tm4[tm].control = value & 0x3ff; 368 /* XXX Stop if running (shouldn't happen) */ 369 if ((value & (1 << 7)) || !(tm & 1)) 370 s->tm4[tm].freq = 371 pxa2xx_timer4_freq[(value & (1 << 8)) ? 0 : (value & 7)]; 372 else { 373 s->tm4[tm].freq = 0; 374 pxa2xx_timer_update4(s, qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL), tm); 375 } 376 break; 377 default: 378 badreg: 379 hw_error("pxa2xx_timer_write: Bad offset " REG_FMT "\n", offset); 380 } 381 } 382 383 static const MemoryRegionOps pxa2xx_timer_ops = { 384 .read = pxa2xx_timer_read, 385 .write = pxa2xx_timer_write, 386 .endianness = DEVICE_NATIVE_ENDIAN, 387 }; 388 389 static void pxa2xx_timer_tick(void *opaque) 390 { 391 PXA2xxTimer0 *t = (PXA2xxTimer0 *) opaque; 392 PXA2xxTimerInfo *i = t->info; 393 394 if (i->irq_enabled & (1 << t->num)) { 395 i->events |= 1 << t->num; 396 qemu_irq_raise(t->irq); 397 } 398 399 if (t->num == 3) 400 if (i->reset3 & 1) { 401 i->reset3 = 0; 402 qemu_system_reset_request(); 403 } 404 } 405 406 static void pxa2xx_timer_tick4(void *opaque) 407 { 408 PXA2xxTimer4 *t = (PXA2xxTimer4 *) opaque; 409 PXA2xxTimerInfo *i = (PXA2xxTimerInfo *) t->tm.info; 410 411 pxa2xx_timer_tick(&t->tm); 412 if (t->control & (1 << 3)) 413 t->clock = 0; 414 if (t->control & (1 << 6)) 415 pxa2xx_timer_update4(i, qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL), t->tm.num - 4); 416 if (i->events & 0xff0) 417 qemu_irq_raise(i->irq4); 418 } 419 420 static int pxa25x_timer_post_load(void *opaque, int version_id) 421 { 422 PXA2xxTimerInfo *s = (PXA2xxTimerInfo *) opaque; 423 int64_t now; 424 int i; 425 426 now = qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL); 427 pxa2xx_timer_update(s, now); 428 429 if (pxa2xx_timer_has_tm4(s)) 430 for (i = 0; i < 8; i ++) 431 pxa2xx_timer_update4(s, now, i); 432 433 return 0; 434 } 435 436 static int pxa2xx_timer_init(SysBusDevice *dev) 437 { 438 PXA2xxTimerInfo *s = PXA2XX_TIMER(dev); 439 int i; 440 441 s->irq_enabled = 0; 442 s->oldclock = 0; 443 s->clock = 0; 444 s->lastload = qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL); 445 s->reset3 = 0; 446 447 for (i = 0; i < 4; i ++) { 448 s->timer[i].value = 0; 449 sysbus_init_irq(dev, &s->timer[i].irq); 450 s->timer[i].info = s; 451 s->timer[i].num = i; 452 s->timer[i].qtimer = timer_new_ns(QEMU_CLOCK_VIRTUAL, 453 pxa2xx_timer_tick, &s->timer[i]); 454 } 455 if (s->flags & (1 << PXA2XX_TIMER_HAVE_TM4)) { 456 sysbus_init_irq(dev, &s->irq4); 457 458 for (i = 0; i < 8; i ++) { 459 s->tm4[i].tm.value = 0; 460 s->tm4[i].tm.info = s; 461 s->tm4[i].tm.num = i + 4; 462 s->tm4[i].freq = 0; 463 s->tm4[i].control = 0x0; 464 s->tm4[i].tm.qtimer = timer_new_ns(QEMU_CLOCK_VIRTUAL, 465 pxa2xx_timer_tick4, &s->tm4[i]); 466 } 467 } 468 469 memory_region_init_io(&s->iomem, OBJECT(s), &pxa2xx_timer_ops, s, 470 "pxa2xx-timer", 0x00001000); 471 sysbus_init_mmio(dev, &s->iomem); 472 473 return 0; 474 } 475 476 static const VMStateDescription vmstate_pxa2xx_timer0_regs = { 477 .name = "pxa2xx_timer0", 478 .version_id = 2, 479 .minimum_version_id = 2, 480 .fields = (VMStateField[]) { 481 VMSTATE_UINT32(value, PXA2xxTimer0), 482 VMSTATE_END_OF_LIST(), 483 }, 484 }; 485 486 static const VMStateDescription vmstate_pxa2xx_timer4_regs = { 487 .name = "pxa2xx_timer4", 488 .version_id = 1, 489 .minimum_version_id = 1, 490 .fields = (VMStateField[]) { 491 VMSTATE_STRUCT(tm, PXA2xxTimer4, 1, 492 vmstate_pxa2xx_timer0_regs, PXA2xxTimer0), 493 VMSTATE_INT32(oldclock, PXA2xxTimer4), 494 VMSTATE_INT32(clock, PXA2xxTimer4), 495 VMSTATE_UINT64(lastload, PXA2xxTimer4), 496 VMSTATE_UINT32(freq, PXA2xxTimer4), 497 VMSTATE_UINT32(control, PXA2xxTimer4), 498 VMSTATE_END_OF_LIST(), 499 }, 500 }; 501 502 static bool pxa2xx_timer_has_tm4_test(void *opaque, int version_id) 503 { 504 return pxa2xx_timer_has_tm4(opaque); 505 } 506 507 static const VMStateDescription vmstate_pxa2xx_timer_regs = { 508 .name = "pxa2xx_timer", 509 .version_id = 1, 510 .minimum_version_id = 1, 511 .post_load = pxa25x_timer_post_load, 512 .fields = (VMStateField[]) { 513 VMSTATE_INT32(clock, PXA2xxTimerInfo), 514 VMSTATE_INT32(oldclock, PXA2xxTimerInfo), 515 VMSTATE_UINT64(lastload, PXA2xxTimerInfo), 516 VMSTATE_STRUCT_ARRAY(timer, PXA2xxTimerInfo, 4, 1, 517 vmstate_pxa2xx_timer0_regs, PXA2xxTimer0), 518 VMSTATE_UINT32(events, PXA2xxTimerInfo), 519 VMSTATE_UINT32(irq_enabled, PXA2xxTimerInfo), 520 VMSTATE_UINT32(reset3, PXA2xxTimerInfo), 521 VMSTATE_UINT32(snapshot, PXA2xxTimerInfo), 522 VMSTATE_STRUCT_ARRAY_TEST(tm4, PXA2xxTimerInfo, 8, 523 pxa2xx_timer_has_tm4_test, 0, 524 vmstate_pxa2xx_timer4_regs, PXA2xxTimer4), 525 VMSTATE_END_OF_LIST(), 526 } 527 }; 528 529 static Property pxa25x_timer_dev_properties[] = { 530 DEFINE_PROP_UINT32("freq", PXA2xxTimerInfo, freq, PXA25X_FREQ), 531 DEFINE_PROP_BIT("tm4", PXA2xxTimerInfo, flags, 532 PXA2XX_TIMER_HAVE_TM4, false), 533 DEFINE_PROP_END_OF_LIST(), 534 }; 535 536 static void pxa25x_timer_dev_class_init(ObjectClass *klass, void *data) 537 { 538 DeviceClass *dc = DEVICE_CLASS(klass); 539 540 dc->desc = "PXA25x timer"; 541 dc->props = pxa25x_timer_dev_properties; 542 } 543 544 static const TypeInfo pxa25x_timer_dev_info = { 545 .name = "pxa25x-timer", 546 .parent = TYPE_PXA2XX_TIMER, 547 .instance_size = sizeof(PXA2xxTimerInfo), 548 .class_init = pxa25x_timer_dev_class_init, 549 }; 550 551 static Property pxa27x_timer_dev_properties[] = { 552 DEFINE_PROP_UINT32("freq", PXA2xxTimerInfo, freq, PXA27X_FREQ), 553 DEFINE_PROP_BIT("tm4", PXA2xxTimerInfo, flags, 554 PXA2XX_TIMER_HAVE_TM4, true), 555 DEFINE_PROP_END_OF_LIST(), 556 }; 557 558 static void pxa27x_timer_dev_class_init(ObjectClass *klass, void *data) 559 { 560 DeviceClass *dc = DEVICE_CLASS(klass); 561 562 dc->desc = "PXA27x timer"; 563 dc->props = pxa27x_timer_dev_properties; 564 } 565 566 static const TypeInfo pxa27x_timer_dev_info = { 567 .name = "pxa27x-timer", 568 .parent = TYPE_PXA2XX_TIMER, 569 .instance_size = sizeof(PXA2xxTimerInfo), 570 .class_init = pxa27x_timer_dev_class_init, 571 }; 572 573 static void pxa2xx_timer_class_init(ObjectClass *oc, void *data) 574 { 575 DeviceClass *dc = DEVICE_CLASS(oc); 576 SysBusDeviceClass *sdc = SYS_BUS_DEVICE_CLASS(oc); 577 578 sdc->init = pxa2xx_timer_init; 579 dc->vmsd = &vmstate_pxa2xx_timer_regs; 580 } 581 582 static const TypeInfo pxa2xx_timer_type_info = { 583 .name = TYPE_PXA2XX_TIMER, 584 .parent = TYPE_SYS_BUS_DEVICE, 585 .instance_size = sizeof(PXA2xxTimerInfo), 586 .abstract = true, 587 .class_init = pxa2xx_timer_class_init, 588 }; 589 590 static void pxa2xx_timer_register_types(void) 591 { 592 type_register_static(&pxa2xx_timer_type_info); 593 type_register_static(&pxa25x_timer_dev_info); 594 type_register_static(&pxa27x_timer_dev_info); 595 } 596 597 type_init(pxa2xx_timer_register_types) 598