[openfirmware] r1013 - dev/olpc/cafenand

svn at openfirmware.info svn at openfirmware.info
Thu Dec 4 10:17:44 CET 2008


Author: wmb
Date: 2008-12-04 10:17:43 +0100 (Thu, 04 Dec 2008)
New Revision: 1013

Modified:
   dev/olpc/cafenand/cafenand.fth
   dev/olpc/cafenand/configure.fth
   dev/olpc/cafenand/lbanand.fth
Log:
OLPC NAND driver - speedup sequential writes by using the cached-write
feature that some chips have.

Modified: dev/olpc/cafenand/cafenand.fth
===================================================================
--- dev/olpc/cafenand/cafenand.fth	2008-12-04 09:17:39 UTC (rev 1012)
+++ dev/olpc/cafenand/cafenand.fth	2008-12-04 09:17:43 UTC (rev 1013)
@@ -37,6 +37,11 @@
 h#     800 instance value /page
 h#  2.0000 instance value /eblock
 
+\ Chip capabilities
+false instance value interleave?       \ Chip-interleaved simultaneous programming
+false instance value cached-write?     \ Cached write support
+1 instance value #simultaneous-writes  \ Number of planes programmable at once
+
 h# 40 constant /oob
 h# e constant /ecc
 h# e constant bb-offset  \ Location of bad-block table signature in OOB data
@@ -137,17 +142,20 @@
 : dma-off  ( -- )  0 h# 40 cl!  ;
 
 0 value #writes
-: wait-write-done  ( -- error? )
+: (wait-write-done)  ( -- status )
    0               ( status )
    begin           ( status )
      drop          ( )
      read-status   ( status )
      dup h# 40 and ( status flag )
    until           ( status )
+   #writes 1+ to #writes
+;
+: wait-write-done  ( -- error? )
+   (wait-write-done)
    \ If the value is completely 0 I think it means write protect     
    1 and  0<>      ( error? )
    write-disable
-   #writes 1+ to #writes
 ;
 
 \ Assumes that the range doesn't straddle a page boundary
@@ -285,15 +293,54 @@
    dma-release                         ( error? )
 ;
 
-: dma-write-page  ( adr page# -- error? )  \ Size is fixed
+: start-write-page  ( adr page# -- )  \ Size is fixed
    write-enable                          ( adr page# )
    0 set-page                            ( adr )
    h# 800 h# 80e  false dma-setup        ( )
    write-cmd h# 4800.0110 cmd wait-cmd   ( )  \ Auto-ECC, RS, write cmd
+;
+: dma-write-page  ( adr page# -- error? )  \ Size is fixed
+   start-write-page
    wait-write-done                       ( error? )
 \   dma-release
 ;
+: async-write-page  ( adr page# -- prev-error? )
+   wait-write-done  if  2drop true exit  then
+   start-write-page
+   0
+;
 
+: fast-write-pages  ( adr page# #pages -- #written )
+   write-enable
+   dup >r
+   begin  dup  while    ( adr page# #rem r: #pages )
+      over 0 set-page                        ( adr page# #rem )
+      2 pick h# 800 h# 80e  false dma-setup  ( adr page# #rem )
+      write-cmd  h# 4800.0110                ( adr page# #rem cmd cmd2 )
+      cached-write?  if                      ( adr page# #rem cmd cmd2 )
+         2 pick 1 <>  if                     ( adr page# #rem cmd cmd2 )
+            5 +  \ make cmd2 cached write    ( adr page# #rem cmd cmd2 )
+         then                                ( adr page# #rem cmd cmd2 )
+      then                                   ( adr page# #rem cmd cmd2 )
+      cmd wait-cmd                           ( adr page# #rem )
+      \ For normal write, this waits for completion.
+      \ For cached write, it waits until the cache register is free.
+      (wait-write-done)  dup 3 and  if       ( adr page# #rem status )
+         \ If the 2 bit is set, the error was on the previous page
+         \ during the program operation.  Otherwise the error was
+         \ on the current page during the download.
+         2 and  if  1+   then                ( adr page# #rem )
+         \ Calculate #written
+         nip nip  r> swap - exit
+      else                                   ( adr page# #rem status )
+         drop                                ( adr page# #rem )
+      then                                   ( adr page# #rem )
+      rot h# 800 +  rot 1+  rot 1-           ( adr' page#' #rem' )
+   repeat              ( adr page# #rem r: #pages )
+   3drop r>
+   write-disable
+;
+
 : write-page   ( adr page# -- error? )  dma-write-page  ;
 : write-bytes  ( adr len page# offset -- error? )  pio-write-raw  ;
 

Modified: dev/olpc/cafenand/configure.fth
===================================================================
--- dev/olpc/cafenand/configure.fth	2008-12-04 09:17:39 UTC (rev 1012)
+++ dev/olpc/cafenand/configure.fth	2008-12-04 09:17:43 UTC (rev 1013)
@@ -51,7 +51,15 @@
    to pages/chip  
 ;  
 
+: configure-capabilities  ( adr -- adr )
+   dup 2 + c@                ( adr id3 )
+   dup h# 80 and 0<> to cached-write?
+   dup h# 40 and 0<> to interleave?
+   4 rshift 3 and   1 swap lshift  to #simultaneous-writes
+;
+
 : configure-auto  ( adr -- adr )
+   configure-capabilities
    pages-auto
    configure-size
 ;

Modified: dev/olpc/cafenand/lbanand.fth
===================================================================
--- dev/olpc/cafenand/lbanand.fth	2008-12-04 09:17:39 UTC (rev 1012)
+++ dev/olpc/cafenand/lbanand.fth	2008-12-04 09:17:43 UTC (rev 1013)
@@ -18,7 +18,7 @@
    tuck set-page                            ( adr #sectors )
    sectors>bytes                            ( adr #bytes )
    dup  false dma-setup                     ( )
-   h# e220.0080 h# 0000.0110 cmd wait-cmd   ( )  \ No ECC, write cmd
+   h# e220.0080 h# 0000.0110 cmd            ( )  \ No ECC, write cmd
    wait-write-done                          ( error? )
 \   dma-release
 ;




More information about the openfirmware mailing list