1
From 2fde986e484d388efeada6e870ee30646a681317 Mon Sep 17 00:00:00 2001
2
From: Peter Maydell <peter.maydell@linaro.org>
3
Date: Mon, 18 Feb 2013 16:58:24 +0000
4
Subject: [PATCH 10/71] omap_gptimer: Support ticks-per-sec > 32 bit values
6
TODO: need to review this change still
8
hw/timer/omap_gptimer.c | 37 +++++++++++++++++++++++++++++--------
9
1 file changed, 29 insertions(+), 8 deletions(-)
11
diff --git a/hw/timer/omap_gptimer.c b/hw/timer/omap_gptimer.c
12
index ac389d8..10cf5d1 100644
13
--- a/hw/timer/omap_gptimer.c
14
+++ b/hw/timer/omap_gptimer.c
15
@@ -100,11 +100,19 @@ static inline void omap_gp_timer_out(struct omap_gp_timer_s *timer, int level)
17
static inline uint32_t omap_gp_timer_read(struct omap_gp_timer_s *timer)
20
+ uint64_t distance, rate;
22
if (timer->st && timer->rate) {
23
distance = qemu_get_clock_ns(vm_clock) - timer->time;
24
- distance = muldiv64(distance, timer->rate, timer->ticks_per_sec);
26
+ /*if ticks_per_sec is bigger than 32bit we cannot use muldiv64*/
27
+ if (timer->ticks_per_sec > 0xffffffff) {
28
+ distance /= get_ticks_per_sec() / 1000; /*distance ms*/
29
+ rate = timer->rate >> (timer->pre ? timer->ptv + 1 : 0);
30
+ distance = muldiv64(distance, rate, 1000);
32
+ distance = muldiv64(distance, timer->rate, timer->ticks_per_sec);
35
if (distance >= 0xffffffff - timer->val)
37
@@ -124,19 +132,32 @@ static inline void omap_gp_timer_sync(struct omap_gp_timer_s *timer)
39
static inline void omap_gp_timer_update(struct omap_gp_timer_s *timer)
41
- int64_t expires, matches;
42
+ int64_t expires, matches, rate;
44
if (timer->st && timer->rate) {
45
- expires = muldiv64(0x100000000ll - timer->val,
46
- timer->ticks_per_sec, timer->rate);
47
+ if (timer->ticks_per_sec > 0xffffffff) {
48
+ rate = timer->rate >> (timer->pre ? timer->ptv + 1 : 0);
49
+ expires = muldiv64(0x100000000ll - timer->val,
50
+ get_ticks_per_sec(), rate);
52
+ expires = muldiv64(0x100000000ll - timer->val,
53
+ timer->ticks_per_sec, timer->rate);
55
qemu_mod_timer(timer->timer, timer->time + expires);
57
if (timer->ce && timer->match_val >= timer->val) {
58
- matches = muldiv64(timer->match_val - timer->val,
59
- timer->ticks_per_sec, timer->rate);
60
+ if (timer->ticks_per_sec > 0xffffffff) {
61
+ rate = timer->rate >> (timer->pre ? timer->ptv + 1 : 0);
62
+ matches = muldiv64(timer->match_val - timer->val,
63
+ get_ticks_per_sec(), rate);
65
+ matches = muldiv64(timer->match_val - timer->val,
66
+ timer->ticks_per_sec, timer->rate);
68
qemu_mod_timer(timer->match, timer->time + matches);
71
qemu_del_timer(timer->match);
74
qemu_del_timer(timer->timer);
75
qemu_del_timer(timer->match);