[openfirmware] [commit] r2678 - cpu/arm/mmp2

repository service svn at openfirmware.info
Wed Nov 9 06:00:22 CET 2011


Author: wmb
Date: Wed Nov  9 06:00:22 2011
New Revision: 2678
URL: http://tracker.coreboot.org/trac/openfirmware/changeset/2678

Log:
OLPC XO-1.75 - fixed high speed TWSI operation based on new information about how the registers work.

Modified:
   cpu/arm/mmp2/twsi.fth

Modified: cpu/arm/mmp2/twsi.fth
==============================================================================
--- cpu/arm/mmp2/twsi.fth	Tue Nov  8 20:20:58 2011	(r2677)
+++ cpu/arm/mmp2/twsi.fth	Wed Nov  9 06:00:22 2011	(r2678)
@@ -15,11 +15,13 @@
 : sr@   ( -- n )  twsi-chip h# 18 + io@   ;
 : sar@  ( -- n )  twsi-chip h# 20 + io@   ;
 : lcr@  ( -- n )  twsi-chip h# 28 + io@   ;
+: wcr@  ( -- n )  twsi-chip h# 30 + io@   ;
 : dbr!  ( n -- )  twsi-chip h# 08 + io!   ;
 : cr!   ( n -- )  twsi-chip h# 10 + io!   ;
 : sr!   ( n -- )  twsi-chip h# 18 + io!   ;
 : sar!  ( n -- )  twsi-chip h# 20 + io!   ;
 : lcr!  ( n -- )  twsi-chip h# 28 + io!   ;
+: wcr!  ( -- n )  twsi-chip h# 30 + io!   ;
 
 create channel-bases
 h# 011000 ,  h# 031000 ,  h# 032000 ,  h# 033000 ,  h# 033800 ,  h# 034000 ,
@@ -58,6 +60,10 @@
 
 h# 1000 constant BBU_TWSI_TimeOut          \ TWSI bus timeout loop counter value
 
+d#   26 constant ftwsi-mhz  \ 
+d# 1400 constant tlow-nsec  \ The I2C spec calls for Tlow >= 1300 ns
+ftwsi-mhz tlow-nsec d# 1000 */ constant tlow-ticks
+
 bbu_ICR_IUE bbu_ICR_SCLE or value cr-set   \ bits to maintain as set
 : init-twsi-channel  ( channel# -- )
    set-twsi-channel
@@ -67,6 +73,9 @@
    cr-set cr!                    \ Release the reset
    0 sar!                        \ Set host slave address
    0 cr!                         \ Disable interrupts
+   \ The COUNT field of TWSI_WCR establishes a minimum value for the SCL low time.
+   \ The minimum Tlow is the clock period * (12 + 2*COUNT)
+   wcr@ h# 1f invert and  tlow-ticks d# 12 - 2/  or  wcr!  \ Setup and hold times
 ;
 : init-twsi  ( -- )
    7 1  do  i init-twsi-channel  loop
@@ -177,25 +186,25 @@
    twsi-out
 ;
 
-: set-bus-standard  cr-set  h# fffe7fff and              to cr-set  ;
-: set-bus-fast      cr-set  h# fffe7fff and  h# 8000 or  to cr-set  ;
 
-\ The dividends below (12,600,000 and 11,600,000) are chosen to give the
-\ same values that the LCR defaults to for the data rates 100,000 and 400,000
-\ The TWSI input clock is the 26 MHz VCXO, and the divided value generates
-\ both the low phase and the high phase, so you would think that the dividend
-\ should be 13,000,000 (half of 26M), but that doesn't give the right result.
-\ Perhaps there is an additive factor in the divisor; the manual is quite vague.
+: set-bus-standard  cr-set  h# 18000 invert and              to cr-set  ;
+: set-bus-fast      cr-set  h# 18000 invert and  h# 8000 or  to cr-set  ;
+
 : set-bus-speed  ( hz -- )  \ Useful range is 25K .. 400K - 100K and 400K are typical
    child-address set-twsi-target                         ( hz )
-   dup  d# 100,000 <=  if                                ( hz )
-      set-bus-standard                                   ( hz )
-      d# 12,600,000  swap /  h# 1ff min  h# 7e max       ( divisor )
+   ftwsi-mhz d# 1,000,000  2 pick */                     ( hz ticks )
+   swap  d# 100,000 <=  if                               ( ticks )
+      \ In slow mode, Thi = Tclk * (8+slv), Tlow = Tclk * (1+slv)
+      9 -  2/ 1+                                         ( slv )
       lcr@ h# 1ff invert and  or  lcr!                   ( )
-   else                                                  ( hz )
-      set-bus-fast                                       ( hz )
-      d# 11,600,000  swap /  h# 1ff min  h# 1d max       ( divisor ) 
-      lcr@ h# 3.fe00 invert and  swap 9 lshift or  lcr!  ( )
+      set-bus-standard                                   ( )
+   else                                                  ( ticks )
+      \ (The information below is poorly documented and was determined empirically)
+      \ In fast mode, Thi = Tclk * (10+flv), Tlo = Tclk * max(1+flv, tlow_ticks))
+      dup d# 11 - 2/ 1+  tlow-ticks  max                 ( ticks ticks-low )
+      -  d# 10 -                                         ( flv )
+      9 lshift  lcr@ h# 3.fe00 invert and  or  lcr!      ( )
+      set-bus-fast                                       ( )
    then                                                  ( )
 ;
 : decode-unit  ( adr len -- low high )  parse-2int  ;



More information about the openfirmware mailing list