changeset 3402:4e19dd426332

devs/nand/micron_mt29: Add 'nand_mt29f_funs_with_ecc' function suite.
author Ross Younger <wry@ecoscentric.com>
date Fri, 26 Sep 2014 22:27:03 +1200
parents 579e9a8938b1
children 8c8767bb9a62
files packages/devs/nand/micron_mt29/current/ChangeLog packages/devs/nand/micron_mt29/current/include/mt29f_generic_lp.inl
diffstat 2 files changed, 62 insertions(+), 28 deletions(-) [+]
line wrap: on
line diff
--- a/packages/devs/nand/micron_mt29/current/ChangeLog
+++ b/packages/devs/nand/micron_mt29/current/ChangeLog
@@ -1,3 +1,7 @@
+2014-09-26  Ross Younger  <wry@eCosCentric.com>
+    * include/mt29f_generic_lp.inl: Add 'nand_mt29f_funs_with_ecc'
+	function suite.
+
 2014-02-13  James G. Smith  <jsmith@ecoscentric.com>
 
 	* include/mt29f_generic_lp.inl (MT29F2G08AAD): Add MT29F2G08AAD
--- a/packages/devs/nand/micron_mt29/current/include/mt29f_generic_lp.inl
+++ b/packages/devs/nand/micron_mt29/current/include/mt29f_generic_lp.inl
@@ -6,37 +6,37 @@
 //      NOTE: This file should only be included by mt29f_generic.inl.
 //
 //=============================================================================
-// ####ECOSGPLCOPYRIGHTBEGIN####                                            
-// -------------------------------------------                              
-// This file is part of eCos, the Embedded Configurable Operating System.   
+// ####ECOSGPLCOPYRIGHTBEGIN####
+// -------------------------------------------
+// This file is part of eCos, the Embedded Configurable Operating System.
 // Copyright (C) 2010 eCosCentric Limited.
 //
-// eCos is free software; you can redistribute it and/or modify it under    
-// the terms of the GNU General Public License as published by the Free     
-// Software Foundation; either version 2 or (at your option) any later      
-// version.                                                                 
+// eCos is free software; you can redistribute it and/or modify it under
+// the terms of the GNU General Public License as published by the Free
+// Software Foundation; either version 2 or (at your option) any later
+// version.
 //
-// eCos is distributed in the hope that it will be useful, but WITHOUT      
-// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or    
-// FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License    
-// for more details.                                                        
+// eCos is distributed in the hope that it will be useful, but WITHOUT
+// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+// FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+// for more details.
 //
-// You should have received a copy of the GNU General Public License        
-// along with eCos; if not, write to the Free Software Foundation, Inc.,    
-// 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.            
+// You should have received a copy of the GNU General Public License
+// along with eCos; if not, write to the Free Software Foundation, Inc.,
+// 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
 //
-// As a special exception, if other files instantiate templates or use      
-// macros or inline functions from this file, or you compile this file      
-// and link it with other works to produce a work based on this file,       
-// this file does not by itself cause the resulting work to be covered by   
-// the GNU General Public License. However the source code for this file    
-// must still be made available in accordance with section (3) of the GNU   
-// General Public License v2.                                               
+// As a special exception, if other files instantiate templates or use
+// macros or inline functions from this file, or you compile this file
+// and link it with other works to produce a work based on this file,
+// this file does not by itself cause the resulting work to be covered by
+// the GNU General Public License. However the source code for this file
+// must still be made available in accordance with section (3) of the GNU
+// General Public License v2.
 //
-// This exception does not invalidate any other reasons why a work based    
-// on this file might be covered by the GNU General Public License.         
-// -------------------------------------------                              
-// ####ECOSGPLCOPYRIGHTEND####                                              
+// This exception does not invalidate any other reasons why a work based
+// on this file might be covered by the GNU General Public License.
+// -------------------------------------------
+// ####ECOSGPLCOPYRIGHTEND####
 //=============================================================================
 //#####DESCRIPTIONBEGIN####
 //
@@ -78,13 +78,14 @@ static inline void change_write_column_l
 {
     write_cmd(dev,0x85);
     write_addr_col_lp(dev,col);
-    // We must wait at least tADL (100ns) before writing further. 
+    // We must wait at least tADL (100ns) before writing further.
     HAL_DELAY_US(1); // TODO: 1us is a bit wasteful; prefer a tighter sleep duration
 }
 
 int nand_mt29f_read_begin(cyg_nand_device *dev, cyg_nand_page_addr page)
 {
-    //mt29f_priv *priv = dev->priv;
+    mt29f_priv *priv = dev->priv;
+    priv->pagestash = page;
 
     NAND_CHATTER(7,dev,"Reading page %d\n",page);
     LOCK(dev);
@@ -110,11 +111,26 @@ int nand_mt29f_read_finish(cyg_nand_devi
         change_read_column_lp(dev, 1 << dev->page_bits);
         read_data_bulk(dev, spare, spare_size);
     }
-    //mt29f_reset(dev,5); // Unnecessary?
     UNLOCK(dev);
     return 0;
 }
 
+int nand_mt29f_read_finish_check(cyg_nand_device *dev, void * spare, size_t spare_size)
+{
+    mt29f_priv *priv = dev->priv;
+    int rv = 0;
+    if (spare && spare_size) {
+        change_read_column_lp(dev, 1 << dev->page_bits);
+        read_data_bulk(dev, spare, spare_size);
+    }
+    if (read_status(dev) & 1) {
+        NAND_ERROR(dev, "mt29f: Read failed ECC check! Page %u", priv->pagestash);
+        rv =-EIO;
+    }
+    UNLOCK(dev);
+    return rv;
+}
+
 int nand_mt29f_read_part(cyg_nand_device *dev, void *dest,
                         cyg_nand_page_addr page, size_t offset, size_t length)
 {
@@ -213,6 +229,15 @@ CYG_NAND_FUNS_V2(nand_mt29f_funs, nand_m
         nand_mt29f_write_begin, nand_mt29f_write_stride, nand_mt29f_write_finish,
         nand_mt29f_erase_block, nand_mt29f_factorybad_lp);
 
+/* Some newer chips have on-board ECC that requires you to perform
+ * a READ_STATUS after reading out a page.
+ * See also mt29f2g08_oob_ecc. */
+CYG_NAND_FUNS_V2(nand_mt29f_funs_with_ecc, nand_mt29f_devinit,
+        nand_mt29f_read_begin, nand_mt29f_read_stride, nand_mt29f_read_finish_check,
+        nand_mt29f_read_part,
+        nand_mt29f_write_begin, nand_mt29f_write_stride, nand_mt29f_write_finish,
+        nand_mt29f_erase_block, nand_mt29f_factorybad_lp);
+
 // key: SUBTYPE( id[1], id[3],   // ReadID response, 2nd and 4th bytes
 //              descriptive string,
 //              log2(number of blocks),
@@ -223,6 +248,11 @@ CYG_NAND_FUNS_V2(nand_mt29f_funs, nand_m
 #define MT29F2G08AAC MT29F_SUBTYPE(0xda, 0x15, "MT29F2G08AAC", 11, 28, 3)
 #define MT29F2G08ABD MT29F_SUBTYPE(0xaa, 0x15, "MT29F2G08ABD", 11, 28, 3)
 #define MT29F2G08AAD MT29F_SUBTYPE(0xda, 0x95, "MT29F2G08AAD", 11, 28, 3)
+#define MT29F2G08ABA MT29F2G08AAD /* SEE NOTE */
+
+/* NOTE: MT29F2G08AAD and MT29F2G08ABA share the same device ID but have
+ * slightly different semantics. ABA has on-board ECC, use
+ * nand_mt29f_funs_with_ecc and mt29f2g08_oob_ecc. */
 #endif
 
 #ifdef CYGFUN_NAND_MICRON_MT29F_4G