[openfirmware] [commit] r2894 - cpu/arm/mmp2
repository service
svn at openfirmware.info
Fri Mar 16 02:02:28 CET 2012
Author: wmb
Date: Fri Mar 16 02:02:28 2012
New Revision: 2894
URL: http://tracker.coreboot.org/trac/openfirmware/changeset/2894
Log:
ARM MMP2 timer driver - improved the code that reads the timer values. The technique I was using to ensure a self-consistent read was bogus, and the hardware documentation is extremely unclear. It turns out that you need to use different techniques for the different timers - careful write/read synchronization for the fast one, and read-until-match for the slower ones.
Modified:
cpu/arm/mmp2/timer.fth
Modified: cpu/arm/mmp2/timer.fth
==============================================================================
--- cpu/arm/mmp2/timer.fth Thu Mar 15 00:19:06 2012 (r2893)
+++ cpu/arm/mmp2/timer.fth Fri Mar 16 02:02:28 2012 (r2894)
@@ -21,37 +21,46 @@
7 h# 84 timer!
;
-[ifdef] arm-assembler
+\ The first ldr usually returns stale data; the second one returns good data.
+\ Empirically, draining the write buffer does not help.
+\ Read-until-match doesn't work with the fast clock because it never matches.
code timer0@ ( -- n ) \ 6.5 MHz
psh tos,sp
set r1,`h# 014000 +io #`
mov r0,#1
str r0,[r1,#0xa4]
- mov r0,r0
- ldr tos,[r1,#0x28]
+ ldr tos,[r1,#0xa4]
+ ldr tos,[r1,#0xa4]
c;
+\ For the slower timers, we use the read-until-match technique.
+\ Apparently the freeze register doesn't update until the next
+\ clock tick, so using it doesn't work well for the slow clocks.
code timer1@ ( -- n ) \ 32.768 kHz
psh tos,sp
set r1,`h# 014000 +io #`
- mov r0,#1
- str r0,[r1,#0xa8]
- mov r0,r0
ldr tos,[r1,#0x2c]
+ begin
+ mov r0,tos
+ ldr tos,[r1,#0x2c]
+ cmps tos,r0
+ = until
c;
code timer2@ ( -- n ) \ 1 kHz
psh tos,sp
set r1,`h# 014000 +io #`
- mov r0,#1
- str r0,[r1,#0xac]
- mov r0,r0
ldr tos,[r1,#0x30]
+ begin
+ mov r0,tos
+ ldr tos,[r1,#0x30]
+ cmps tos,r0
+ = until
c;
[else]
-: timer0@ ( -- n ) 1 h# 0140a4 io! h# 014028 io@ ;
-: timer1@ ( -- n ) 1 h# 0140a8 io! h# 01402c io@ ;
-: timer2@ ( -- n ) 1 h# 0140ac io! h# 014030 io@ ;
+: timer0@ ( -- n ) 1 h# 0140a4 io! h# 0140a4 io@ drop h# 0140a4 io@ ;
+: timer1@ ( -- n ) 1 h# 0140a8 io! h# 0140a8 io@ drop h# 0140a8 io@ ;
+: timer2@ ( -- n ) 1 h# 0140ac io! h# 0140ac io@ drop h# 0140ac io@ ;
[then]
: timer0-status@ ( -- n ) h# 014034 io@ ;
More information about the openfirmware
mailing list