[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