1 #include <aros/debug.h>
2 #include <asm/mpc5200b.h>
4 #include <aros/asmcall.h>
5 #include <exec/execbase.h>
8 #include <proto/exec.h>
9 #include <proto/timer.h>
13 // tick2usec - 64424510 for 66.666666MHz
14 // tick2usec - 130150524 for 33.000000MHz
16 inline uint32_t __attribute__((const)) tick2usec(uint32_t tick
)
19 uint64_t tmp
= ((uint64_t)tick
) * 130150524;
21 retval
= (tmp
+ 0x7fffffff) >> 32;
26 inline uint32_t __attribute__((const)) usec2tick(uint32_t usec
)
29 // uint64_t tmp = ((uint64_t)usec) * 286331150203ULL;
31 // retval = (tmp + 0x7fffffff) >> 32;
38 void EClockUpdate(struct TimerBase
*TimerBase
)
45 diff
= (time
- TimerBase
->tb_prev_tick
);
46 TimerBase
->tb_prev_tick
= time
;
48 TimerBase
->tb_ticks_total
+= diff
;
50 TimerBase
->tb_ticks_sec
+= diff
;
51 TimerBase
->tb_ticks_elapsed
+= diff
;
53 if (TimerBase
->tb_ticks_sec
>= 33000000)
55 TimerBase
->tb_ticks_sec
-= 33000000;
56 TimerBase
->tb_CurrentTime
.tv_secs
++;
61 if (TimerBase
->tb_ticks_elapsed
>= 33000000)
63 TimerBase
->tb_ticks_elapsed
-= 33000000;
64 TimerBase
->tb_Elapsed
.tv_secs
++;
67 TimerBase
->tb_Elapsed
.tv_micro
= tick2usec(TimerBase
->tb_ticks_elapsed
);
68 TimerBase
->tb_CurrentTime
.tv_micro
= tick2usec(TimerBase
->tb_ticks_sec
);
72 // bug("[timer] CurrentTime: %d:%06d\n", TimerBase->tb_CurrentTime.tv_secs, TimerBase->tb_CurrentTime.tv_micro);
73 // bug("[timer] %08x %08x %d %d \n", tbc_expected, tbc_achieved, tbc_achieved-tbc_expected, corr);
77 void EClockSet(struct TimerBase
*TimerBase
)
79 TimerBase
->tb_ticks_sec
= usec2tick(TimerBase
->tb_CurrentTime
.tv_micro
);
82 extern volatile slt_t
*slice_timer
;
84 void TimerSetup(struct TimerBase
*TimerBase
, uint32_t waste
)
86 int32_t delay
= 660000; /* 50Hz in worst case */
88 struct timerequest
*tr
;
89 uint32_t current_time
;
91 tr
= (struct timerequest
*)GetHead(&TimerBase
->tb_Lists
[TL_WAITVBL
]);
95 time
.tv_micro
= tr
->tr_time
.tv_micro
;
96 time
.tv_secs
= tr
->tr_time
.tv_secs
;
98 SubTime(&time
, &TimerBase
->tb_CurrentTime
);
100 if ((LONG
)time
.tv_secs
< 0)
104 else if (time
.tv_secs
== 0)
106 // if (time.tv_micro < 20000)
108 if (delay
> usec2tick(time
.tv_micro
))
109 delay
= usec2tick(time
.tv_micro
);
114 tr
= (struct timerequest
*)GetHead(&TimerBase
->tb_Lists
[TL_VBLANK
]);
118 time
.tv_micro
= tr
->tr_time
.tv_micro
;
119 time
.tv_secs
= tr
->tr_time
.tv_secs
;
121 SubTime(&time
, &TimerBase
->tb_Elapsed
);
123 if ((LONG
)time
.tv_secs
< 0)
127 else if (time
.tv_secs
== 0)
129 // if (time.tv_micro < 20000)
131 if (delay
> usec2tick(time
.tv_micro
))
132 delay
= usec2tick(time
.tv_micro
);
137 current_time
= mftbl();
138 delay
-= ((int32_t)(current_time
- waste
)) + corr
;
140 if (delay
< 256) delay
= 256;
142 tbc_expected
= current_time
+ delay
;
145 outl(SLT_CF_INTRENA
, &slice_timer
->slt_cf
);
147 outl(delay
, &slice_timer
->slt_tc
);
149 outl(SLT_CF_INTRENA
| SLT_CF_ENABLE
, &slice_timer
->slt_cf
);
150 /* Clear interrupt request. */
151 outl(SLT_TS_ST
, &slice_timer
->slt_ts
);