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 case A_TCORB: 225 if (size == 1) { 226 return tmr->tcorb[ch]; 227 } else { 228 return concat_reg(tmr->tcorb); 229 } 230 case A_TCNT: 231 return read_tcnt(tmr, size, ch); 232 case A_TCCR: 233 if (size == 1) { 234 return read_tccr(tmr->tccr[ch]); 235 } else { 236 return read_tccr(tmr->tccr[0]) << 8 | read_tccr(tmr->tccr[1]); 237 } 238 default: 239 qemu_log_mask(LOG_UNIMP, "renesas_tmr: Register 0x%" HWADDR_PRIX 240 " not implemented\n", 241 addr); 242 break; 243 } 244 return UINT64_MAX; 245 } 246 247 static void tmr_write_count(RTMRState *tmr, int ch, unsigned size, 248 uint8_t *reg, uint64_t val) 249 { 250 if (size == 1) { 251 reg[ch] = val; 252 update_events(tmr, ch); 253 } else { 254 reg[0] = extract32(val, 8, 8); 255 reg[1] = extract32(val, 0, 8); 256 update_events(tmr, 0); 257 update_events(tmr, 1); 258 } 259 } 260 261 static void tmr_write(void *opaque, hwaddr addr, uint64_t val, unsigned size) 262 { 263 RTMRState *tmr = opaque; 264 int ch = addr & 1; 265 266 if (size == 2 && (ch != 0 || addr == A_TCR || addr == A_TCSR)) { 267 qemu_log_mask(LOG_GUEST_ERROR, 268 "renesas_tmr: Invalid write size 0x%" HWADDR_PRIX "\n", 269 addr); 270 return; 271 } 272 switch (addr & 0x0e) { 273 case A_TCR: 274 tmr->tcr[ch] = val; 275 break; 276 case A_TCSR: 277 tmr->tcsr[ch] = val; 278 break; 279 case A_TCORA: 280 tmr_write_count(tmr, ch, size, tmr->tcora, val); 281 break; 282 case A_TCORB: 283 tmr_write_count(tmr, ch, size, tmr->tcorb, val); 284 break; 285 case A_TCNT: 286 tmr_write_count(tmr, ch, size, tmr->tcnt, val); 287 break; 288 case A_TCCR: 289 tmr_write_count(tmr, ch, size, tmr->tccr, val); 290 break; 291 default: 292 qemu_log_mask(LOG_UNIMP, "renesas_tmr: Register 0x%" HWADDR_PRIX 293 " not implemented\n", 294 addr); 295 break; 296 } 297 } 298 299 static const MemoryRegionOps tmr_ops = { 300 .write = tmr_write, 301 .read = tmr_read, 302 .endianness = DEVICE_LITTLE_ENDIAN, 303 .impl = { 304 .min_access_size = 1, 305 .max_access_size = 2, 306 }, 307 .valid = { 308 .min_access_size = 1, 309 .max_access_size = 2, 310 }, 311 }; 312 313 static void timer_events(RTMRState *tmr, int ch); 314 315 static uint16_t issue_event(RTMRState *tmr, int ch, int sz, 316 uint16_t tcnt, uint16_t tcora, uint16_t tcorb) 317 { 318 uint16_t ret = tcnt; 319 320 switch (tmr->next[ch]) { 321 case none: 322 break; 323 case cmia: 324 if (tcnt >= tcora) { 325 if (FIELD_EX8(tmr->tcr[ch], TCR, CCLR) == CCLR_A) { 326 ret = tcnt - tcora; 327 } 328 if (FIELD_EX8(tmr->tcr[ch], TCR, CMIEA)) { 329 qemu_irq_pulse(tmr->cmia[ch]); 330 } 331 if (sz == 8 && ch == 0 && 332 FIELD_EX8(tmr->tccr[1], TCCR, CSS) == CASCADING) { 333 tmr->tcnt[1]++; 334 timer_events(tmr, 1); 335 } 336 } 337 break; 338 case cmib: 339 if (tcnt >= tcorb) { 340 if (FIELD_EX8(tmr->tcr[ch], TCR, CCLR) == CCLR_B) { 341 ret = tcnt - tcorb; 342 } 343 if (FIELD_EX8(tmr->tcr[ch], TCR, CMIEB)) { 344 qemu_irq_pulse(tmr->cmib[ch]); 345 } 346 } 347 break; 348 case ovi: 349 if ((tcnt >= (1 << sz)) && FIELD_EX8(tmr->tcr[ch], TCR, OVIE)) { 350 qemu_irq_pulse(tmr->ovi[ch]); 351 } 352 break; 353 default: 354 g_assert_not_reached(); 355 } 356 return ret; 357 } 358 359 static void timer_events(RTMRState *tmr, int ch) 360 { 361 uint16_t tcnt; 362 363 tmr->tcnt[ch] = read_tcnt(tmr, 1, ch); 364 if (FIELD_EX8(tmr->tccr[0], TCCR, CSS) != CASCADING) { 365 tmr->tcnt[ch] = issue_event(tmr, ch, 8, 366 tmr->tcnt[ch], 367 tmr->tcora[ch], 368 tmr->tcorb[ch]) & 0xff; 369 } else { 370 if (ch == 1) { 371 return ; 372 } 373 tcnt = issue_event(tmr, ch, 16, 374 concat_reg(tmr->tcnt), 375 concat_reg(tmr->tcora), 376 concat_reg(tmr->tcorb)); 377 tmr->tcnt[0] = (tcnt >> 8) & 0xff; 378 tmr->tcnt[1] = tcnt & 0xff; 379 } 380 update_events(tmr, ch); 381 } 382 383 static void timer_event0(void *opaque) 384 { 385 RTMRState *tmr = opaque; 386 387 timer_events(tmr, 0); 388 } 389 390 static void timer_event1(void *opaque) 391 { 392 RTMRState *tmr = opaque; 393 394 timer_events(tmr, 1); 395 } 396 397 static void rtmr_reset(DeviceState *dev) 398 { 399 RTMRState *tmr = RTMR(dev); 400 tmr->tcr[0] = tmr->tcr[1] = 0x00; 401 tmr->tcsr[0] = 0x00; 402 tmr->tcsr[1] = 0x10; 403 tmr->tcnt[0] = tmr->tcnt[1] = 0x00; 404 tmr->tcora[0] = tmr->tcora[1] = 0xff; 405 tmr->tcorb[0] = tmr->tcorb[1] = 0xff; 406 tmr->tccr[0] = tmr->tccr[1] = 0x00; 407 tmr->next[0] = tmr->next[1] = none; 408 tmr->tick = qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL); 409 } 410 411 static void rtmr_init(Object *obj) 412 { 413 SysBusDevice *d = SYS_BUS_DEVICE(obj); 414 RTMRState *tmr = RTMR(obj); 415 int i; 416 417 memory_region_init_io(&tmr->memory, OBJECT(tmr), &tmr_ops, 418 tmr, "renesas-tmr", 0x10); 419 sysbus_init_mmio(d, &tmr->memory); 420 421 for (i = 0; i < ARRAY_SIZE(tmr->ovi); i++) { 422 sysbus_init_irq(d, &tmr->cmia[i]); 423 sysbus_init_irq(d, &tmr->cmib[i]); 424 sysbus_init_irq(d, &tmr->ovi[i]); 425 } 426 timer_init_ns(&tmr->timer[0], QEMU_CLOCK_VIRTUAL, timer_event0, tmr); 427 timer_init_ns(&tmr->timer[1], QEMU_CLOCK_VIRTUAL, timer_event1, tmr); 428 } 429 430 static const VMStateDescription vmstate_rtmr = { 431 .name = "rx-tmr", 432 .version_id = 1, 433 .minimum_version_id = 1, 434 .fields = (VMStateField[]) { 435 VMSTATE_INT64(tick, RTMRState), 436 VMSTATE_UINT8_ARRAY(tcnt, RTMRState, TMR_CH), 437 VMSTATE_UINT8_ARRAY(tcora, RTMRState, TMR_CH), 438 VMSTATE_UINT8_ARRAY(tcorb, RTMRState, TMR_CH), 439 VMSTATE_UINT8_ARRAY(tcr, RTMRState, TMR_CH), 440 VMSTATE_UINT8_ARRAY(tccr, RTMRState, TMR_CH), 441 VMSTATE_UINT8_ARRAY(tcor, RTMRState, TMR_CH), 442 VMSTATE_UINT8_ARRAY(tcsr, RTMRState, TMR_CH), 443 VMSTATE_INT64_ARRAY(div_round, RTMRState, TMR_CH), 444 VMSTATE_UINT8_ARRAY(next, RTMRState, TMR_CH), 445 VMSTATE_TIMER_ARRAY(timer, RTMRState, TMR_CH), 446 VMSTATE_END_OF_LIST() 447 } 448 }; 449 450 static Property rtmr_properties[] = { 451 DEFINE_PROP_UINT64("input-freq", RTMRState, input_freq, 0), 452 DEFINE_PROP_END_OF_LIST(), 453 }; 454 455 static void rtmr_class_init(ObjectClass *klass, void *data) 456 { 457 DeviceClass *dc = DEVICE_CLASS(klass); 458 459 dc->vmsd = &vmstate_rtmr; 460 dc->reset = rtmr_reset; 461 device_class_set_props(dc, rtmr_properties); 462 } 463 464 static const TypeInfo rtmr_info = { 465 .name = TYPE_RENESAS_TMR, 466 .parent = TYPE_SYS_BUS_DEVICE, 467 .instance_size = sizeof(RTMRState), 468 .instance_init = rtmr_init, 469 .class_init = rtmr_class_init, 470 }; 471 472 static void rtmr_register_types(void) 473 { 474 type_register_static(&rtmr_info); 475 } 476 477 type_init(rtmr_register_types) 478