1 /* 2 * ASPEED AST2400 Timer 3 * 4 * Andrew Jeffery <andrew@aj.id.au> 5 * 6 * Copyright (C) 2016 IBM Corp. 7 * 8 * This code is licensed under the GPL version 2 or later. See 9 * the COPYING file in the top-level directory. 10 */ 11 12 #include "qemu/osdep.h" 13 #include "qapi/error.h" 14 #include "hw/irq.h" 15 #include "hw/sysbus.h" 16 #include "hw/timer/aspeed_timer.h" 17 #include "qemu/bitops.h" 18 #include "qemu/timer.h" 19 #include "qemu/log.h" 20 #include "qemu/module.h" 21 #include "trace.h" 22 23 #define TIMER_NR_REGS 4 24 25 #define TIMER_CTRL_BITS 4 26 #define TIMER_CTRL_MASK ((1 << TIMER_CTRL_BITS) - 1) 27 28 #define TIMER_CLOCK_USE_EXT true 29 #define TIMER_CLOCK_EXT_HZ 1000000 30 #define TIMER_CLOCK_USE_APB false 31 32 #define TIMER_REG_STATUS 0 33 #define TIMER_REG_RELOAD 1 34 #define TIMER_REG_MATCH_FIRST 2 35 #define TIMER_REG_MATCH_SECOND 3 36 37 #define TIMER_FIRST_CAP_PULSE 4 38 39 enum timer_ctrl_op { 40 op_enable = 0, 41 op_external_clock, 42 op_overflow_interrupt, 43 op_pulse_enable 44 }; 45 46 /** 47 * Avoid mutual references between AspeedTimerCtrlState and AspeedTimer 48 * structs, as it's a waste of memory. The ptimer BH callback needs to know 49 * whether a specific AspeedTimer is enabled, but this information is held in 50 * AspeedTimerCtrlState. So, provide a helper to hoist ourselves from an 51 * arbitrary AspeedTimer to AspeedTimerCtrlState. 52 */ 53 static inline AspeedTimerCtrlState *timer_to_ctrl(AspeedTimer *t) 54 { 55 const AspeedTimer (*timers)[] = (void *)t - (t->id * sizeof(*t)); 56 return container_of(timers, AspeedTimerCtrlState, timers); 57 } 58 59 static inline bool timer_ctrl_status(AspeedTimer *t, enum timer_ctrl_op op) 60 { 61 return !!(timer_to_ctrl(t)->ctrl & BIT(t->id * TIMER_CTRL_BITS + op)); 62 } 63 64 static inline bool timer_enabled(AspeedTimer *t) 65 { 66 return timer_ctrl_status(t, op_enable); 67 } 68 69 static inline bool timer_overflow_interrupt(AspeedTimer *t) 70 { 71 return timer_ctrl_status(t, op_overflow_interrupt); 72 } 73 74 static inline bool timer_can_pulse(AspeedTimer *t) 75 { 76 return t->id >= TIMER_FIRST_CAP_PULSE; 77 } 78 79 static inline bool timer_external_clock(AspeedTimer *t) 80 { 81 return timer_ctrl_status(t, op_external_clock); 82 } 83 84 static inline uint32_t calculate_rate(struct AspeedTimer *t) 85 { 86 AspeedTimerCtrlState *s = timer_to_ctrl(t); 87 88 return timer_external_clock(t) ? TIMER_CLOCK_EXT_HZ : s->scu->apb_freq; 89 } 90 91 static inline uint32_t calculate_ticks(struct AspeedTimer *t, uint64_t now_ns) 92 { 93 uint64_t delta_ns = now_ns - MIN(now_ns, t->start); 94 uint32_t rate = calculate_rate(t); 95 uint64_t ticks = muldiv64(delta_ns, rate, NANOSECONDS_PER_SECOND); 96 97 return t->reload - MIN(t->reload, ticks); 98 } 99 100 static inline uint64_t calculate_time(struct AspeedTimer *t, uint32_t ticks) 101 { 102 uint64_t delta_ns; 103 uint64_t delta_ticks; 104 105 delta_ticks = t->reload - MIN(t->reload, ticks); 106 delta_ns = muldiv64(delta_ticks, NANOSECONDS_PER_SECOND, calculate_rate(t)); 107 108 return t->start + delta_ns; 109 } 110 111 static inline uint32_t calculate_match(struct AspeedTimer *t, int i) 112 { 113 return t->match[i] < t->reload ? t->match[i] : 0; 114 } 115 116 static uint64_t calculate_next(struct AspeedTimer *t) 117 { 118 uint64_t now = qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL); 119 uint64_t next; 120 121 /* 122 * We don't know the relationship between the values in the match 123 * registers, so sort using MAX/MIN/zero. We sort in that order as 124 * the timer counts down to zero. 125 */ 126 127 next = calculate_time(t, MAX(calculate_match(t, 0), calculate_match(t, 1))); 128 if (now < next) { 129 return next; 130 } 131 132 next = calculate_time(t, MIN(calculate_match(t, 0), calculate_match(t, 1))); 133 if (now < next) { 134 return next; 135 } 136 137 next = calculate_time(t, 0); 138 if (now < next) { 139 return next; 140 } 141 142 /* We've missed all deadlines, fire interrupt and try again */ 143 timer_del(&t->timer); 144 145 if (timer_overflow_interrupt(t)) { 146 t->level = !t->level; 147 qemu_set_irq(t->irq, t->level); 148 } 149 150 next = MAX(MAX(calculate_match(t, 0), calculate_match(t, 1)), 0); 151 t->start = qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL); 152 153 return calculate_time(t, next); 154 } 155 156 static void aspeed_timer_mod(AspeedTimer *t) 157 { 158 uint64_t next = calculate_next(t); 159 if (next) { 160 timer_mod(&t->timer, next); 161 } 162 } 163 164 static void aspeed_timer_expire(void *opaque) 165 { 166 AspeedTimer *t = opaque; 167 bool interrupt = false; 168 uint32_t ticks; 169 170 if (!timer_enabled(t)) { 171 return; 172 } 173 174 ticks = calculate_ticks(t, qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL)); 175 176 if (!ticks) { 177 interrupt = timer_overflow_interrupt(t) || !t->match[0] || !t->match[1]; 178 } else if (ticks <= MIN(t->match[0], t->match[1])) { 179 interrupt = true; 180 } else if (ticks <= MAX(t->match[0], t->match[1])) { 181 interrupt = true; 182 } 183 184 if (interrupt) { 185 t->level = !t->level; 186 qemu_set_irq(t->irq, t->level); 187 } 188 189 aspeed_timer_mod(t); 190 } 191 192 static uint64_t aspeed_timer_get_value(AspeedTimer *t, int reg) 193 { 194 uint64_t value; 195 196 switch (reg) { 197 case TIMER_REG_STATUS: 198 if (timer_enabled(t)) { 199 value = calculate_ticks(t, qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL)); 200 } else { 201 value = t->reload; 202 } 203 break; 204 case TIMER_REG_RELOAD: 205 value = t->reload; 206 break; 207 case TIMER_REG_MATCH_FIRST: 208 case TIMER_REG_MATCH_SECOND: 209 value = t->match[reg - 2]; 210 break; 211 default: 212 qemu_log_mask(LOG_UNIMP, "%s: Programming error: unexpected reg: %d\n", 213 __func__, reg); 214 value = 0; 215 break; 216 } 217 return value; 218 } 219 220 static uint64_t aspeed_timer_read(void *opaque, hwaddr offset, unsigned size) 221 { 222 AspeedTimerCtrlState *s = opaque; 223 const int reg = (offset & 0xf) / 4; 224 uint64_t value; 225 226 switch (offset) { 227 case 0x30: /* Control Register */ 228 value = s->ctrl; 229 break; 230 case 0x34: /* Control Register 2 */ 231 value = s->ctrl2; 232 break; 233 case 0x00 ... 0x2c: /* Timers 1 - 4 */ 234 value = aspeed_timer_get_value(&s->timers[(offset >> 4)], reg); 235 break; 236 case 0x40 ... 0x8c: /* Timers 5 - 8 */ 237 value = aspeed_timer_get_value(&s->timers[(offset >> 4) - 1], reg); 238 break; 239 /* Illegal */ 240 case 0x38: 241 case 0x3C: 242 default: 243 qemu_log_mask(LOG_GUEST_ERROR, "%s: Bad offset 0x%" HWADDR_PRIx "\n", 244 __func__, offset); 245 value = 0; 246 break; 247 } 248 trace_aspeed_timer_read(offset, size, value); 249 return value; 250 } 251 252 static void aspeed_timer_set_value(AspeedTimerCtrlState *s, int timer, int reg, 253 uint32_t value) 254 { 255 AspeedTimer *t; 256 uint32_t old_reload; 257 258 trace_aspeed_timer_set_value(timer, reg, value); 259 t = &s->timers[timer]; 260 switch (reg) { 261 case TIMER_REG_RELOAD: 262 old_reload = t->reload; 263 t->reload = value; 264 265 /* If the reload value was not previously set, or zero, and 266 * the current value is valid, try to start the timer if it is 267 * enabled. 268 */ 269 if (old_reload || !t->reload) { 270 break; 271 } 272 273 case TIMER_REG_STATUS: 274 if (timer_enabled(t)) { 275 uint64_t now = qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL); 276 int64_t delta = (int64_t) value - (int64_t) calculate_ticks(t, now); 277 uint32_t rate = calculate_rate(t); 278 279 if (delta >= 0) { 280 t->start += muldiv64(delta, NANOSECONDS_PER_SECOND, rate); 281 } else { 282 t->start -= muldiv64(-delta, NANOSECONDS_PER_SECOND, rate); 283 } 284 aspeed_timer_mod(t); 285 } 286 break; 287 case TIMER_REG_MATCH_FIRST: 288 case TIMER_REG_MATCH_SECOND: 289 t->match[reg - 2] = value; 290 if (timer_enabled(t)) { 291 aspeed_timer_mod(t); 292 } 293 break; 294 default: 295 qemu_log_mask(LOG_UNIMP, "%s: Programming error: unexpected reg: %d\n", 296 __func__, reg); 297 break; 298 } 299 } 300 301 /* Control register operations are broken out into helpers that can be 302 * explicitly called on aspeed_timer_reset(), but also from 303 * aspeed_timer_ctrl_op(). 304 */ 305 306 static void aspeed_timer_ctrl_enable(AspeedTimer *t, bool enable) 307 { 308 trace_aspeed_timer_ctrl_enable(t->id, enable); 309 if (enable) { 310 t->start = qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL); 311 aspeed_timer_mod(t); 312 } else { 313 timer_del(&t->timer); 314 } 315 } 316 317 static void aspeed_timer_ctrl_external_clock(AspeedTimer *t, bool enable) 318 { 319 trace_aspeed_timer_ctrl_external_clock(t->id, enable); 320 } 321 322 static void aspeed_timer_ctrl_overflow_interrupt(AspeedTimer *t, bool enable) 323 { 324 trace_aspeed_timer_ctrl_overflow_interrupt(t->id, enable); 325 } 326 327 static void aspeed_timer_ctrl_pulse_enable(AspeedTimer *t, bool enable) 328 { 329 if (timer_can_pulse(t)) { 330 trace_aspeed_timer_ctrl_pulse_enable(t->id, enable); 331 } else { 332 qemu_log_mask(LOG_GUEST_ERROR, 333 "%s: Timer does not support pulse mode\n", __func__); 334 } 335 } 336 337 /** 338 * Given the actions are fixed in number and completely described in helper 339 * functions, dispatch with a lookup table rather than manage control flow with 340 * a switch statement. 341 */ 342 static void (*const ctrl_ops[])(AspeedTimer *, bool) = { 343 [op_enable] = aspeed_timer_ctrl_enable, 344 [op_external_clock] = aspeed_timer_ctrl_external_clock, 345 [op_overflow_interrupt] = aspeed_timer_ctrl_overflow_interrupt, 346 [op_pulse_enable] = aspeed_timer_ctrl_pulse_enable, 347 }; 348 349 /** 350 * Conditionally affect changes chosen by a timer's control bit. 351 * 352 * The aspeed_timer_ctrl_op() interface is convenient for the 353 * aspeed_timer_set_ctrl() function as the "no change" early exit can be 354 * calculated for all operations, which cleans up the caller code. However the 355 * interface isn't convenient for the reset function where we want to enter a 356 * specific state without artificially constructing old and new values that 357 * will fall through the change guard (and motivates extracting the actions 358 * out to helper functions). 359 * 360 * @t: The timer to manipulate 361 * @op: The type of operation to be performed 362 * @old: The old state of the timer's control bits 363 * @new: The incoming state for the timer's control bits 364 */ 365 static void aspeed_timer_ctrl_op(AspeedTimer *t, enum timer_ctrl_op op, 366 uint8_t old, uint8_t new) 367 { 368 const uint8_t mask = BIT(op); 369 const bool enable = !!(new & mask); 370 const bool changed = ((old ^ new) & mask); 371 if (!changed) { 372 return; 373 } 374 ctrl_ops[op](t, enable); 375 } 376 377 static void aspeed_timer_set_ctrl(AspeedTimerCtrlState *s, uint32_t reg) 378 { 379 int i; 380 int shift; 381 uint8_t t_old, t_new; 382 AspeedTimer *t; 383 const uint8_t enable_mask = BIT(op_enable); 384 385 /* Handle a dependency between the 'enable' and remaining three 386 * configuration bits - i.e. if more than one bit in the control set has 387 * changed, including the 'enable' bit, then we want either disable the 388 * timer and perform configuration, or perform configuration and then 389 * enable the timer 390 */ 391 for (i = 0; i < ASPEED_TIMER_NR_TIMERS; i++) { 392 t = &s->timers[i]; 393 shift = (i * TIMER_CTRL_BITS); 394 t_old = (s->ctrl >> shift) & TIMER_CTRL_MASK; 395 t_new = (reg >> shift) & TIMER_CTRL_MASK; 396 397 /* If we are disabling, do so first */ 398 if ((t_old & enable_mask) && !(t_new & enable_mask)) { 399 aspeed_timer_ctrl_enable(t, false); 400 } 401 aspeed_timer_ctrl_op(t, op_external_clock, t_old, t_new); 402 aspeed_timer_ctrl_op(t, op_overflow_interrupt, t_old, t_new); 403 aspeed_timer_ctrl_op(t, op_pulse_enable, t_old, t_new); 404 /* If we are enabling, do so last */ 405 if (!(t_old & enable_mask) && (t_new & enable_mask)) { 406 aspeed_timer_ctrl_enable(t, true); 407 } 408 } 409 s->ctrl = reg; 410 } 411 412 static void aspeed_timer_set_ctrl2(AspeedTimerCtrlState *s, uint32_t value) 413 { 414 trace_aspeed_timer_set_ctrl2(value); 415 } 416 417 static void aspeed_timer_write(void *opaque, hwaddr offset, uint64_t value, 418 unsigned size) 419 { 420 const uint32_t tv = (uint32_t)(value & 0xFFFFFFFF); 421 const int reg = (offset & 0xf) / 4; 422 AspeedTimerCtrlState *s = opaque; 423 424 switch (offset) { 425 /* Control Registers */ 426 case 0x30: 427 aspeed_timer_set_ctrl(s, tv); 428 break; 429 case 0x34: 430 aspeed_timer_set_ctrl2(s, tv); 431 break; 432 /* Timer Registers */ 433 case 0x00 ... 0x2c: 434 aspeed_timer_set_value(s, (offset >> TIMER_NR_REGS), reg, tv); 435 break; 436 case 0x40 ... 0x8c: 437 aspeed_timer_set_value(s, (offset >> TIMER_NR_REGS) - 1, reg, tv); 438 break; 439 /* Illegal */ 440 case 0x38: 441 case 0x3C: 442 default: 443 qemu_log_mask(LOG_GUEST_ERROR, "%s: Bad offset 0x%" HWADDR_PRIx "\n", 444 __func__, offset); 445 break; 446 } 447 } 448 449 static const MemoryRegionOps aspeed_timer_ops = { 450 .read = aspeed_timer_read, 451 .write = aspeed_timer_write, 452 .endianness = DEVICE_LITTLE_ENDIAN, 453 .valid.min_access_size = 4, 454 .valid.max_access_size = 4, 455 .valid.unaligned = false, 456 }; 457 458 static void aspeed_init_one_timer(AspeedTimerCtrlState *s, uint8_t id) 459 { 460 AspeedTimer *t = &s->timers[id]; 461 462 t->id = id; 463 timer_init_ns(&t->timer, QEMU_CLOCK_VIRTUAL, aspeed_timer_expire, t); 464 } 465 466 static void aspeed_timer_realize(DeviceState *dev, Error **errp) 467 { 468 int i; 469 SysBusDevice *sbd = SYS_BUS_DEVICE(dev); 470 AspeedTimerCtrlState *s = ASPEED_TIMER(dev); 471 Object *obj; 472 Error *err = NULL; 473 474 obj = object_property_get_link(OBJECT(dev), "scu", &err); 475 if (!obj) { 476 error_propagate_prepend(errp, err, "required link 'scu' not found: "); 477 return; 478 } 479 s->scu = ASPEED_SCU(obj); 480 481 for (i = 0; i < ASPEED_TIMER_NR_TIMERS; i++) { 482 aspeed_init_one_timer(s, i); 483 sysbus_init_irq(sbd, &s->timers[i].irq); 484 } 485 memory_region_init_io(&s->iomem, OBJECT(s), &aspeed_timer_ops, s, 486 TYPE_ASPEED_TIMER, 0x1000); 487 sysbus_init_mmio(sbd, &s->iomem); 488 } 489 490 static void aspeed_timer_reset(DeviceState *dev) 491 { 492 int i; 493 AspeedTimerCtrlState *s = ASPEED_TIMER(dev); 494 495 for (i = 0; i < ASPEED_TIMER_NR_TIMERS; i++) { 496 AspeedTimer *t = &s->timers[i]; 497 /* Explicitly call helpers to avoid any conditional behaviour through 498 * aspeed_timer_set_ctrl(). 499 */ 500 aspeed_timer_ctrl_enable(t, false); 501 aspeed_timer_ctrl_external_clock(t, TIMER_CLOCK_USE_APB); 502 aspeed_timer_ctrl_overflow_interrupt(t, false); 503 aspeed_timer_ctrl_pulse_enable(t, false); 504 t->level = 0; 505 t->reload = 0; 506 t->match[0] = 0; 507 t->match[1] = 0; 508 } 509 s->ctrl = 0; 510 s->ctrl2 = 0; 511 } 512 513 static const VMStateDescription vmstate_aspeed_timer = { 514 .name = "aspeed.timer", 515 .version_id = 2, 516 .minimum_version_id = 2, 517 .fields = (VMStateField[]) { 518 VMSTATE_UINT8(id, AspeedTimer), 519 VMSTATE_INT32(level, AspeedTimer), 520 VMSTATE_TIMER(timer, AspeedTimer), 521 VMSTATE_UINT32(reload, AspeedTimer), 522 VMSTATE_UINT32_ARRAY(match, AspeedTimer, 2), 523 VMSTATE_END_OF_LIST() 524 } 525 }; 526 527 static const VMStateDescription vmstate_aspeed_timer_state = { 528 .name = "aspeed.timerctrl", 529 .version_id = 1, 530 .minimum_version_id = 1, 531 .fields = (VMStateField[]) { 532 VMSTATE_UINT32(ctrl, AspeedTimerCtrlState), 533 VMSTATE_UINT32(ctrl2, AspeedTimerCtrlState), 534 VMSTATE_STRUCT_ARRAY(timers, AspeedTimerCtrlState, 535 ASPEED_TIMER_NR_TIMERS, 1, vmstate_aspeed_timer, 536 AspeedTimer), 537 VMSTATE_END_OF_LIST() 538 } 539 }; 540 541 static void timer_class_init(ObjectClass *klass, void *data) 542 { 543 DeviceClass *dc = DEVICE_CLASS(klass); 544 545 dc->realize = aspeed_timer_realize; 546 dc->reset = aspeed_timer_reset; 547 dc->desc = "ASPEED Timer"; 548 dc->vmsd = &vmstate_aspeed_timer_state; 549 } 550 551 static const TypeInfo aspeed_timer_info = { 552 .name = TYPE_ASPEED_TIMER, 553 .parent = TYPE_SYS_BUS_DEVICE, 554 .instance_size = sizeof(AspeedTimerCtrlState), 555 .class_init = timer_class_init, 556 }; 557 558 static void aspeed_timer_register_types(void) 559 { 560 type_register_static(&aspeed_timer_info); 561 } 562 563 type_init(aspeed_timer_register_types) 564