Lines Matching +full:8 +full:- +full:ch

2  * Renesas 8bit timer
9 * SPDX-License-Identifier: GPL-2.0-or-later
28 #include "hw/qdev-properties.h"
43 REG8(TCNT, 8)
56 static const int clkdiv[] = {0, 1, 2, 8, 32, 64, 1024, 8192};
60 return (reg[0] << 8) | reg[1]; in concat_reg()
63 static void update_events(RTMRState *tmr, int ch) in update_events() argument
69 if (tmr->tccr[ch] == 0) { in update_events()
72 if (FIELD_EX8(tmr->tccr[ch], TCCR, CSS) == 0) { in update_events()
77 if (FIELD_EX8(tmr->tccr[0], TCCR, CSS) == CSS_CASCADING) { in update_events()
79 if (ch == 1) { in update_events()
80 tmr->next[ch] = none; in update_events()
83 diff[cmia] = concat_reg(tmr->tcora) - concat_reg(tmr->tcnt); in update_events()
84 diff[cmib] = concat_reg(tmr->tcorb) - concat_reg(tmr->tcnt); in update_events()
85 diff[ovi] = 0x10000 - concat_reg(tmr->tcnt); in update_events()
88 diff[cmia] = tmr->tcora[ch] - tmr->tcnt[ch]; in update_events()
89 diff[cmib] = tmr->tcorb[ch] - tmr->tcnt[ch]; in update_events()
90 diff[ovi] = 0x100 - tmr->tcnt[ch]; in update_events()
99 tmr->next[ch] = event; in update_events()
101 next_time *= clkdiv[FIELD_EX8(tmr->tccr[ch], TCCR, CKS)]; in update_events()
103 next_time /= tmr->input_freq; in update_events()
105 timer_mod(&tmr->timer[ch], next_time); in update_events()
108 static int elapsed_time(RTMRState *tmr, int ch, int64_t delta) in elapsed_time() argument
110 int divrate = clkdiv[FIELD_EX8(tmr->tccr[ch], TCCR, CKS)]; in elapsed_time()
113 tmr->div_round[ch] += delta; in elapsed_time()
115 et = tmr->div_round[ch] / divrate; in elapsed_time()
116 tmr->div_round[ch] %= divrate; in elapsed_time()
124 static uint16_t read_tcnt(RTMRState *tmr, unsigned size, int ch) in read_tcnt() argument
131 delta = (now - tmr->tick) * NANOSECONDS_PER_SECOND / tmr->input_freq; in read_tcnt()
133 tmr->tick = now; in read_tcnt()
135 switch (FIELD_EX8(tmr->tccr[1], TCCR, CSS)) { in read_tcnt()
140 ovf = elapsed >> 8; in read_tcnt()
142 tcnt[1] = tmr->tcnt[1] + (elapsed & 0xff); in read_tcnt()
147 tcnt[1] = tmr->tcnt[1]; in read_tcnt()
152 switch (FIELD_EX8(tmr->tccr[0], TCCR, CSS)) { in read_tcnt()
155 tcnt[0] = tmr->tcnt[0] + elapsed; in read_tcnt()
158 tcnt[0] = tmr->tcnt[0] + ovf; in read_tcnt()
162 tcnt[0] = tmr->tcnt[0]; in read_tcnt()
168 tcnt[0] = tmr->tcnt[0]; in read_tcnt()
169 tcnt[1] = tmr->tcnt[1]; in read_tcnt()
172 return tcnt[ch]; in read_tcnt()
175 ret = deposit32(ret, 0, 8, tcnt[1]); in read_tcnt()
176 ret = deposit32(ret, 8, 8, tcnt[0]); in read_tcnt()
196 int ch = addr & 1; in tmr_read() local
199 if (size == 2 && (ch != 0 || addr == A_TCR || addr == A_TCSR)) { in tmr_read()
209 FIELD_EX8(tmr->tcr[ch], TCR, CCLR)); in tmr_read()
211 FIELD_EX8(tmr->tcr[ch], TCR, OVIE)); in tmr_read()
213 FIELD_EX8(tmr->tcr[ch], TCR, CMIEA)); in tmr_read()
215 FIELD_EX8(tmr->tcr[ch], TCR, CMIEB)); in tmr_read()
220 FIELD_EX8(tmr->tcsr[ch], TCSR, OSA)); in tmr_read()
222 FIELD_EX8(tmr->tcsr[ch], TCSR, OSB)); in tmr_read()
223 switch (ch) { in tmr_read()
226 FIELD_EX8(tmr->tcsr[ch], TCSR, ADTE)); in tmr_read()
235 return tmr->tcora[ch]; in tmr_read()
236 } else if (ch == 0) { in tmr_read()
237 return concat_reg(tmr->tcora); in tmr_read()
242 return tmr->tcorb[ch]; in tmr_read()
244 return concat_reg(tmr->tcorb); in tmr_read()
247 return read_tcnt(tmr, size, ch); in tmr_read()
250 return read_tccr(tmr->tccr[ch]); in tmr_read()
252 return read_tccr(tmr->tccr[0]) << 8 | read_tccr(tmr->tccr[1]); in tmr_read()
263 static void tmr_write_count(RTMRState *tmr, int ch, unsigned size, in tmr_write_count() argument
267 reg[ch] = val; in tmr_write_count()
268 update_events(tmr, ch); in tmr_write_count()
270 reg[0] = extract32(val, 8, 8); in tmr_write_count()
271 reg[1] = extract32(val, 0, 8); in tmr_write_count()
280 int ch = addr & 1; in tmr_write() local
282 if (size == 2 && (ch != 0 || addr == A_TCR || addr == A_TCSR)) { in tmr_write()
290 tmr->tcr[ch] = val; in tmr_write()
293 tmr->tcsr[ch] = val; in tmr_write()
296 tmr_write_count(tmr, ch, size, tmr->tcora, val); in tmr_write()
299 tmr_write_count(tmr, ch, size, tmr->tcorb, val); in tmr_write()
302 tmr_write_count(tmr, ch, size, tmr->tcnt, val); in tmr_write()
305 tmr_write_count(tmr, ch, size, tmr->tccr, val); in tmr_write()
329 static void timer_events(RTMRState *tmr, int ch);
331 static uint16_t issue_event(RTMRState *tmr, int ch, int sz, in issue_event() argument
336 switch (tmr->next[ch]) { in issue_event()
341 if (FIELD_EX8(tmr->tcr[ch], TCR, CCLR) == CCLR_A) { in issue_event()
342 ret = tcnt - tcora; in issue_event()
344 if (FIELD_EX8(tmr->tcr[ch], TCR, CMIEA)) { in issue_event()
345 qemu_irq_pulse(tmr->cmia[ch]); in issue_event()
347 if (sz == 8 && ch == 0 && in issue_event()
348 FIELD_EX8(tmr->tccr[1], TCCR, CSS) == CSS_CASCADING) { in issue_event()
349 tmr->tcnt[1]++; in issue_event()
356 if (FIELD_EX8(tmr->tcr[ch], TCR, CCLR) == CCLR_B) { in issue_event()
357 ret = tcnt - tcorb; in issue_event()
359 if (FIELD_EX8(tmr->tcr[ch], TCR, CMIEB)) { in issue_event()
360 qemu_irq_pulse(tmr->cmib[ch]); in issue_event()
365 if ((tcnt >= (1 << sz)) && FIELD_EX8(tmr->tcr[ch], TCR, OVIE)) { in issue_event()
366 qemu_irq_pulse(tmr->ovi[ch]); in issue_event()
375 static void timer_events(RTMRState *tmr, int ch) in timer_events() argument
379 tmr->tcnt[ch] = read_tcnt(tmr, 1, ch); in timer_events()
380 if (FIELD_EX8(tmr->tccr[0], TCCR, CSS) != CSS_CASCADING) { in timer_events()
381 tmr->tcnt[ch] = issue_event(tmr, ch, 8, in timer_events()
382 tmr->tcnt[ch], in timer_events()
383 tmr->tcora[ch], in timer_events()
384 tmr->tcorb[ch]) & 0xff; in timer_events()
386 if (ch == 1) { in timer_events()
389 tcnt = issue_event(tmr, ch, 16, in timer_events()
390 concat_reg(tmr->tcnt), in timer_events()
391 concat_reg(tmr->tcora), in timer_events()
392 concat_reg(tmr->tcorb)); in timer_events()
393 tmr->tcnt[0] = (tcnt >> 8) & 0xff; in timer_events()
394 tmr->tcnt[1] = tcnt & 0xff; in timer_events()
396 update_events(tmr, ch); in timer_events()
416 tmr->tcr[0] = tmr->tcr[1] = 0x00; in rtmr_reset()
417 tmr->tcsr[0] = 0x00; in rtmr_reset()
418 tmr->tcsr[1] = 0x10; in rtmr_reset()
419 tmr->tcnt[0] = tmr->tcnt[1] = 0x00; in rtmr_reset()
420 tmr->tcora[0] = tmr->tcora[1] = 0xff; in rtmr_reset()
421 tmr->tcorb[0] = tmr->tcorb[1] = 0xff; in rtmr_reset()
422 tmr->tccr[0] = tmr->tccr[1] = 0x00; in rtmr_reset()
423 tmr->next[0] = tmr->next[1] = none; in rtmr_reset()
424 tmr->tick = qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL); in rtmr_reset()
433 memory_region_init_io(&tmr->memory, OBJECT(tmr), &tmr_ops, in rtmr_init()
434 tmr, "renesas-tmr", 0x10); in rtmr_init()
435 sysbus_init_mmio(d, &tmr->memory); in rtmr_init()
437 for (i = 0; i < ARRAY_SIZE(tmr->ovi); i++) { in rtmr_init()
438 sysbus_init_irq(d, &tmr->cmia[i]); in rtmr_init()
439 sysbus_init_irq(d, &tmr->cmib[i]); in rtmr_init()
440 sysbus_init_irq(d, &tmr->ovi[i]); in rtmr_init()
442 timer_init_ns(&tmr->timer[0], QEMU_CLOCK_VIRTUAL, timer_event0, tmr); in rtmr_init()
443 timer_init_ns(&tmr->timer[1], QEMU_CLOCK_VIRTUAL, timer_event1, tmr); in rtmr_init()
447 .name = "rx-tmr",
467 DEFINE_PROP_UINT64("input-freq", RTMRState, input_freq, 0),
475 dc->vmsd = &vmstate_rtmr; in rtmr_class_init()