1 /* 2 * Renesas 8bit timer 3 * 4 * Datasheet: RX62N Group, RX621 Group User's Manual: Hardware 5 * (Rev.1.40 R01UH0033EJ0140) 6 * 7 * Copyright (c) 2019 Yoshinori Sato 8 * 9 * SPDX-License-Identifier: GPL-2.0-or-later 10 * 11 * This program is free software; you can redistribute it and/or modify it 12 * under the terms and conditions of the GNU General Public License, 13 * version 2 or later, as published by the Free Software Foundation. 14 * 15 * This program is distributed in the hope it will be useful, but WITHOUT 16 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 17 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for 18 * more details. 19 * 20 * You should have received a copy of the GNU General Public License along with 21 * this program. If not, see <http://www.gnu.org/licenses/>. 22 */ 23 24 #include "qemu/osdep.h" 25 #include "qemu/log.h" 26 #include "hw/irq.h" 27 #include "hw/registerfields.h" 28 #include "hw/qdev-properties.h" 29 #include "hw/timer/renesas_tmr.h" 30 #include "migration/vmstate.h" 31 32 REG8(TCR, 0) 33 FIELD(TCR, CCLR, 3, 2) 34 FIELD(TCR, OVIE, 5, 1) 35 FIELD(TCR, CMIEA, 6, 1) 36 FIELD(TCR, CMIEB, 7, 1) 37 REG8(TCSR, 2) 38 FIELD(TCSR, OSA, 0, 2) 39 FIELD(TCSR, OSB, 2, 2) 40 FIELD(TCSR, ADTE, 4, 2) 41 REG8(TCORA, 4) 42 REG8(TCORB, 6) 43 REG8(TCNT, 8) 44 REG8(TCCR, 10) 45 FIELD(TCCR, CKS, 0, 3) 46 FIELD(TCCR, CSS, 3, 2) 47 FIELD(TCCR, TMRIS, 7, 1) 48 49 #define INTERNAL 0x01 50 #define CASCADING 0x03 51 #define CCLR_A 0x01 52 #define CCLR_B 0x02 53 54 static const int clkdiv[] = {0, 1, 2, 8, 32, 64, 1024, 8192}; 55 56 static uint8_t concat_reg(uint8_t *reg) 57 { 58 return (reg[0] << 8) | reg[1]; 59 } 60 61 static void update_events(RTMRState *tmr, int ch) 62 { 63 uint16_t diff[TMR_NR_EVENTS], min; 64 int64_t next_time; 65 int i, event; 66 67 if (tmr->tccr[ch] == 0) { 68 return ; 69 } 70 if (FIELD_EX8(tmr->tccr[ch], TCCR, CSS) == 0) { 71 /* external clock mode */ 72 /* event not happened */ 73 return ; 74 } 75 if (FIELD_EX8(tmr->tccr[0], TCCR, CSS) == CASCADING) { 76 /* cascading mode */ 77 if (ch == 1) { 78 tmr->next[ch] = none; 79 return ; 80 } 81 diff[cmia] = concat_reg(tmr->tcora) - concat_reg(tmr->tcnt); 82 diff[cmib] = concat_reg(tmr->tcorb) - concat_reg(tmr->tcnt); 83 diff[ovi] = 0x10000 - concat_reg(tmr->tcnt); 84 } else { 85 /* separate mode */ 86 diff[cmia] = tmr->tcora[ch] - tmr->tcnt[ch]; 87 diff[cmib] = tmr->tcorb[ch] - tmr->tcnt[ch]; 88 diff[ovi] = 0x100 - tmr->tcnt[ch]; 89 } 90 /* Search for the most recently occurring event. */ 91 for (event = 0, min = diff[0], i = 1; i < none; i++) { 92 if (min > diff[i]) { 93 event = i; 94 min = diff[i]; 95 } 96 } 97 tmr->next[ch] = event; 98 next_time = diff[event]; 99 next_time *= clkdiv[FIELD_EX8(tmr->tccr[ch], TCCR, CKS)]; 100 next_time *= NANOSECONDS_PER_SECOND; 101 next_time /= tmr->input_freq; 102 next_time += qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL); 103 timer_mod(&tmr->timer[ch], next_time); 104 } 105 106 static int elapsed_time(RTMRState *tmr, int ch, int64_t delta) 107 { 108 int divrate = clkdiv[FIELD_EX8(tmr->tccr[ch], TCCR, CKS)]; 109 int et; 110 111 tmr->div_round[ch] += delta; 112 if (divrate > 0) { 113 et = tmr->div_round[ch] / divrate; 114 tmr->div_round[ch] %= divrate; 115 } else { 116 /* disble clock. so no update */ 117 et = 0; 118 } 119 return et; 120 } 121 122 static uint16_t read_tcnt(RTMRState *tmr, unsigned size, int ch) 123 { 124 int64_t delta, now = qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL); 125 int elapsed, ovf = 0; 126 uint16_t tcnt[2]; 127 uint32_t ret; 128 129 delta = (now - tmr->tick) * NANOSECONDS_PER_SECOND / tmr->input_freq; 130 if (delta > 0) { 131 tmr->tick = now; 132 133 if (FIELD_EX8(tmr->tccr[1], TCCR, CSS) == INTERNAL) { 134 /* timer1 count update */ 135 elapsed = elapsed_time(tmr, 1, delta); 136 if (elapsed >= 0x100) { 137 ovf = elapsed >> 8; 138 } 139 tcnt[1] = tmr->tcnt[1] + (elapsed & 0xff); 140 } 141 switch (FIELD_EX8(tmr->tccr[0], TCCR, CSS)) { 142 case INTERNAL: 143 elapsed = elapsed_time(tmr, 0, delta); 144 tcnt[0] = tmr->tcnt[0] + elapsed; 145 break; 146 case CASCADING: 147 if (ovf > 0) { 148 tcnt[0] = tmr->tcnt[0] + ovf; 149 } 150 break; 151 } 152 } else { 153 tcnt[0] = tmr->tcnt[0]; 154 tcnt[1] = tmr->tcnt[1]; 155 } 156 if (size == 1) { 157 return tcnt[ch]; 158 } else { 159 ret = 0; 160 ret = deposit32(ret, 0, 8, tcnt[1]); 161 ret = deposit32(ret, 8, 8, tcnt[0]); 162 return ret; 163 } 164 } 165 166 static uint8_t read_tccr(uint8_t r) 167 { 168 uint8_t tccr = 0; 169 tccr = FIELD_DP8(tccr, TCCR, TMRIS, 170 FIELD_EX8(r, TCCR, TMRIS)); 171 tccr = FIELD_DP8(tccr, TCCR, CSS, 172 FIELD_EX8(r, TCCR, CSS)); 173 tccr = FIELD_DP8(tccr, TCCR, CKS, 174 FIELD_EX8(r, TCCR, CKS)); 175 return tccr; 176 } 177 178 static uint64_t tmr_read(void *opaque, hwaddr addr, unsigned size) 179 { 180 RTMRState *tmr = opaque; 181 int ch = addr & 1; 182 uint64_t ret; 183 184 if (size == 2 && (ch != 0 || addr == A_TCR || addr == A_TCSR)) { 185 qemu_log_mask(LOG_GUEST_ERROR, "renesas_tmr: Invalid read size 0x%" 186 HWADDR_PRIX "\n", 187 addr); 188 return UINT64_MAX; 189 } 190 switch (addr & 0x0e) { 191 case A_TCR: 192 ret = 0; 193 ret = FIELD_DP8(ret, TCR, CCLR, 194 FIELD_EX8(tmr->tcr[ch], TCR, CCLR)); 195 ret = FIELD_DP8(ret, TCR, OVIE, 196 FIELD_EX8(tmr->tcr[ch], TCR, OVIE)); 197 ret = FIELD_DP8(ret, TCR, CMIEA, 198 FIELD_EX8(tmr->tcr[ch], TCR, CMIEA)); 199 ret = FIELD_DP8(ret, TCR, CMIEB, 200 FIELD_EX8(tmr->tcr[ch], TCR, CMIEB)); 201 return ret; 202 case A_TCSR: 203 ret = 0; 204 ret = FIELD_DP8(ret, TCSR, OSA, 205 FIELD_EX8(tmr->tcsr[ch], TCSR, OSA)); 206 ret = FIELD_DP8(ret, TCSR, OSB, 207 FIELD_EX8(tmr->tcsr[ch], TCSR, OSB)); 208 switch (ch) { 209 case 0: 210 ret = FIELD_DP8(ret, TCSR, ADTE, 211 FIELD_EX8(tmr->tcsr[ch], TCSR, ADTE)); 212 break; 213 case 1: /* CH1 ADTE unimplement always 1 */ 214 ret = FIELD_DP8(ret, TCSR, ADTE, 1); 215 break; 216 } 217 return ret; 218 case A_TCORA: 219 if (size == 1) { 220 return tmr->tcora[ch]; 221 } else if (ch == 0) { 222 return concat_reg(tmr->tcora); 223 } 224 /* fall through */ 225 case A_TCORB: 226 if (size == 1) { 227 return tmr->tcorb[ch]; 228 } else { 229 return concat_reg(tmr->tcorb); 230 } 231 case A_TCNT: 232 return read_tcnt(tmr, size, ch); 233 case A_TCCR: 234 if (size == 1) { 235 return read_tccr(tmr->tccr[ch]); 236 } else { 237 return read_tccr(tmr->tccr[0]) << 8 | read_tccr(tmr->tccr[1]); 238 } 239 default: 240 qemu_log_mask(LOG_UNIMP, "renesas_tmr: Register 0x%" HWADDR_PRIX 241 " not implemented\n", 242 addr); 243 break; 244 } 245 return UINT64_MAX; 246 } 247 248 static void tmr_write_count(RTMRState *tmr, int ch, unsigned size, 249 uint8_t *reg, uint64_t val) 250 { 251 if (size == 1) { 252 reg[ch] = val; 253 update_events(tmr, ch); 254 } else { 255 reg[0] = extract32(val, 8, 8); 256 reg[1] = extract32(val, 0, 8); 257 update_events(tmr, 0); 258 update_events(tmr, 1); 259 } 260 } 261 262 static void tmr_write(void *opaque, hwaddr addr, uint64_t val, unsigned size) 263 { 264 RTMRState *tmr = opaque; 265 int ch = addr & 1; 266 267 if (size == 2 && (ch != 0 || addr == A_TCR || addr == A_TCSR)) { 268 qemu_log_mask(LOG_GUEST_ERROR, 269 "renesas_tmr: Invalid write size 0x%" HWADDR_PRIX "\n", 270 addr); 271 return; 272 } 273 switch (addr & 0x0e) { 274 case A_TCR: 275 tmr->tcr[ch] = val; 276 break; 277 case A_TCSR: 278 tmr->tcsr[ch] = val; 279 break; 280 case A_TCORA: 281 tmr_write_count(tmr, ch, size, tmr->tcora, val); 282 break; 283 case A_TCORB: 284 tmr_write_count(tmr, ch, size, tmr->tcorb, val); 285 break; 286 case A_TCNT: 287 tmr_write_count(tmr, ch, size, tmr->tcnt, val); 288 break; 289 case A_TCCR: 290 tmr_write_count(tmr, ch, size, tmr->tccr, val); 291 break; 292 default: 293 qemu_log_mask(LOG_UNIMP, "renesas_tmr: Register 0x%" HWADDR_PRIX 294 " not implemented\n", 295 addr); 296 break; 297 } 298 } 299 300 static const MemoryRegionOps tmr_ops = { 301 .write = tmr_write, 302 .read = tmr_read, 303 .endianness = DEVICE_LITTLE_ENDIAN, 304 .impl = { 305 .min_access_size = 1, 306 .max_access_size = 2, 307 }, 308 .valid = { 309 .min_access_size = 1, 310 .max_access_size = 2, 311 }, 312 }; 313 314 static void timer_events(RTMRState *tmr, int ch); 315 316 static uint16_t issue_event(RTMRState *tmr, int ch, int sz, 317 uint16_t tcnt, uint16_t tcora, uint16_t tcorb) 318 { 319 uint16_t ret = tcnt; 320 321 switch (tmr->next[ch]) { 322 case none: 323 break; 324 case cmia: 325 if (tcnt >= tcora) { 326 if (FIELD_EX8(tmr->tcr[ch], TCR, CCLR) == CCLR_A) { 327 ret = tcnt - tcora; 328 } 329 if (FIELD_EX8(tmr->tcr[ch], TCR, CMIEA)) { 330 qemu_irq_pulse(tmr->cmia[ch]); 331 } 332 if (sz == 8 && ch == 0 && 333 FIELD_EX8(tmr->tccr[1], TCCR, CSS) == CASCADING) { 334 tmr->tcnt[1]++; 335 timer_events(tmr, 1); 336 } 337 } 338 break; 339 case cmib: 340 if (tcnt >= tcorb) { 341 if (FIELD_EX8(tmr->tcr[ch], TCR, CCLR) == CCLR_B) { 342 ret = tcnt - tcorb; 343 } 344 if (FIELD_EX8(tmr->tcr[ch], TCR, CMIEB)) { 345 qemu_irq_pulse(tmr->cmib[ch]); 346 } 347 } 348 break; 349 case ovi: 350 if ((tcnt >= (1 << sz)) && FIELD_EX8(tmr->tcr[ch], TCR, OVIE)) { 351 qemu_irq_pulse(tmr->ovi[ch]); 352 } 353 break; 354 default: 355 g_assert_not_reached(); 356 } 357 return ret; 358 } 359 360 static void timer_events(RTMRState *tmr, int ch) 361 { 362 uint16_t tcnt; 363 364 tmr->tcnt[ch] = read_tcnt(tmr, 1, ch); 365 if (FIELD_EX8(tmr->tccr[0], TCCR, CSS) != CASCADING) { 366 tmr->tcnt[ch] = issue_event(tmr, ch, 8, 367 tmr->tcnt[ch], 368 tmr->tcora[ch], 369 tmr->tcorb[ch]) & 0xff; 370 } else { 371 if (ch == 1) { 372 return ; 373 } 374 tcnt = issue_event(tmr, ch, 16, 375 concat_reg(tmr->tcnt), 376 concat_reg(tmr->tcora), 377 concat_reg(tmr->tcorb)); 378 tmr->tcnt[0] = (tcnt >> 8) & 0xff; 379 tmr->tcnt[1] = tcnt & 0xff; 380 } 381 update_events(tmr, ch); 382 } 383 384 static void timer_event0(void *opaque) 385 { 386 RTMRState *tmr = opaque; 387 388 timer_events(tmr, 0); 389 } 390 391 static void timer_event1(void *opaque) 392 { 393 RTMRState *tmr = opaque; 394 395 timer_events(tmr, 1); 396 } 397 398 static void rtmr_reset(DeviceState *dev) 399 { 400 RTMRState *tmr = RTMR(dev); 401 tmr->tcr[0] = tmr->tcr[1] = 0x00; 402 tmr->tcsr[0] = 0x00; 403 tmr->tcsr[1] = 0x10; 404 tmr->tcnt[0] = tmr->tcnt[1] = 0x00; 405 tmr->tcora[0] = tmr->tcora[1] = 0xff; 406 tmr->tcorb[0] = tmr->tcorb[1] = 0xff; 407 tmr->tccr[0] = tmr->tccr[1] = 0x00; 408 tmr->next[0] = tmr->next[1] = none; 409 tmr->tick = qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL); 410 } 411 412 static void rtmr_init(Object *obj) 413 { 414 SysBusDevice *d = SYS_BUS_DEVICE(obj); 415 RTMRState *tmr = RTMR(obj); 416 int i; 417 418 memory_region_init_io(&tmr->memory, OBJECT(tmr), &tmr_ops, 419 tmr, "renesas-tmr", 0x10); 420 sysbus_init_mmio(d, &tmr->memory); 421 422 for (i = 0; i < ARRAY_SIZE(tmr->ovi); i++) { 423 sysbus_init_irq(d, &tmr->cmia[i]); 424 sysbus_init_irq(d, &tmr->cmib[i]); 425 sysbus_init_irq(d, &tmr->ovi[i]); 426 } 427 timer_init_ns(&tmr->timer[0], QEMU_CLOCK_VIRTUAL, timer_event0, tmr); 428 timer_init_ns(&tmr->timer[1], QEMU_CLOCK_VIRTUAL, timer_event1, tmr); 429 } 430 431 static const VMStateDescription vmstate_rtmr = { 432 .name = "rx-tmr", 433 .version_id = 1, 434 .minimum_version_id = 1, 435 .fields = (VMStateField[]) { 436 VMSTATE_INT64(tick, RTMRState), 437 VMSTATE_UINT8_ARRAY(tcnt, RTMRState, TMR_CH), 438 VMSTATE_UINT8_ARRAY(tcora, RTMRState, TMR_CH), 439 VMSTATE_UINT8_ARRAY(tcorb, RTMRState, TMR_CH), 440 VMSTATE_UINT8_ARRAY(tcr, RTMRState, TMR_CH), 441 VMSTATE_UINT8_ARRAY(tccr, RTMRState, TMR_CH), 442 VMSTATE_UINT8_ARRAY(tcor, RTMRState, TMR_CH), 443 VMSTATE_UINT8_ARRAY(tcsr, RTMRState, TMR_CH), 444 VMSTATE_INT64_ARRAY(div_round, RTMRState, TMR_CH), 445 VMSTATE_UINT8_ARRAY(next, RTMRState, TMR_CH), 446 VMSTATE_TIMER_ARRAY(timer, RTMRState, TMR_CH), 447 VMSTATE_END_OF_LIST() 448 } 449 }; 450 451 static Property rtmr_properties[] = { 452 DEFINE_PROP_UINT64("input-freq", RTMRState, input_freq, 0), 453 DEFINE_PROP_END_OF_LIST(), 454 }; 455 456 static void rtmr_class_init(ObjectClass *klass, void *data) 457 { 458 DeviceClass *dc = DEVICE_CLASS(klass); 459 460 dc->vmsd = &vmstate_rtmr; 461 dc->reset = rtmr_reset; 462 device_class_set_props(dc, rtmr_properties); 463 } 464 465 static const TypeInfo rtmr_info = { 466 .name = TYPE_RENESAS_TMR, 467 .parent = TYPE_SYS_BUS_DEVICE, 468 .instance_size = sizeof(RTMRState), 469 .instance_init = rtmr_init, 470 .class_init = rtmr_class_init, 471 }; 472 473 static void rtmr_register_types(void) 474 { 475 type_register_static(&rtmr_info); 476 } 477 478 type_init(rtmr_register_types) 479