[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