@ -11,7 +11,7 @@
* Added 16 - bit nand support
* ( C ) 2004 Texas Instruments
*
* Copyright 2010 Freescale Semiconductor
* Copyright 2010 , 2012 Freescale Semiconductor
* The portions of this file whose copyright is held by Freescale and which
* are not considered a derived work of GPL v2 - only code may be distributed
* and / or modified under the terms of the GNU General Public License as
@ -390,6 +390,41 @@ static void nand_print_and_set_info(int idx)
setenv ( " nand_erasesize " , buf ) ;
}
static int raw_access ( nand_info_t * nand , ulong addr , loff_t off , ulong count ,
int read )
{
int ret = 0 ;
size_t rwsize ;
while ( count - - ) {
/* Raw access */
mtd_oob_ops_t ops = {
. datbuf = ( u8 * ) addr ,
. oobbuf = ( ( u8 * ) addr ) + nand - > writesize ,
. len = nand - > writesize ,
. ooblen = nand - > oobsize ,
. mode = MTD_OOB_RAW
} ;
rwsize = nand - > writesize + nand - > oobsize ;
if ( read )
ret = nand - > read_oob ( nand , off , & ops ) ;
else
ret = nand - > write_oob ( nand , off , & ops ) ;
if ( ret ) {
printf ( " %s: error at offset %llx, ret %d \n " ,
__func__ , ( long long ) off , ret ) ;
break ;
}
addr + = nand - > writesize + nand - > oobsize ;
off + = nand - > writesize ;
}
return ret ;
}
int do_nand ( cmd_tbl_t * cmdtp , int flag , int argc , char * const argv [ ] )
{
int i , ret = 0 ;
@ -568,7 +603,9 @@ int do_nand(cmd_tbl_t * cmdtp, int flag, int argc, char * const argv[])
if ( strncmp ( cmd , " read " , 4 ) = = 0 | | strncmp ( cmd , " write " , 5 ) = = 0 ) {
size_t rwsize ;
ulong pagecount = 1 ;
int read ;
int raw ;
if ( argc < 4 )
goto usage ;
@ -577,13 +614,36 @@ int do_nand(cmd_tbl_t * cmdtp, int flag, int argc, char * const argv[])
read = strncmp ( cmd , " read " , 4 ) = = 0 ; /* 1 = read, 0 = write */
printf ( " \n NAND %s: " , read ? " read " : " write " ) ;
if ( arg_off_size ( argc - 3 , argv + 3 , & dev , & off , & size ) ! = 0 )
return 1 ;
nand = & nand_info [ dev ] ;
rwsize = size ;
s = strchr ( cmd , ' . ' ) ;
if ( ! strcmp ( s , " .raw " ) ) {
raw = 1 ;
if ( arg_off ( argv [ 3 ] , & dev , & off , & size ) )
return 1 ;
if ( argc > 4 & & ! str2long ( argv [ 4 ] , & pagecount ) ) {
printf ( " '%s' is not a number \n " , argv [ 4 ] ) ;
return 1 ;
}
if ( pagecount * nand - > writesize > size ) {
puts ( " Size exceeds partition or device limit \n " ) ;
return - 1 ;
}
rwsize = pagecount * ( nand - > writesize + nand - > oobsize ) ;
} else {
if ( arg_off_size ( argc - 3 , argv + 3 , & dev ,
& off , & size ) ! = 0 )
return 1 ;
rwsize = size ;
}
if ( ! s | | ! strcmp ( s , " .jffs2 " ) | |
! strcmp ( s , " .e " ) | | ! strcmp ( s , " .i " ) ) {
if ( read )
@ -609,7 +669,8 @@ int do_nand(cmd_tbl_t * cmdtp, int flag, int argc, char * const argv[])
return 1 ;
}
ret = nand_write_skip_bad ( nand , off , & rwsize ,
( u_char * ) addr , WITH_YAFFS_OOB ) ;
( u_char * ) addr ,
WITH_INLINE_OOB ) ;
# endif
} else if ( ! strcmp ( s , " .oob " ) ) {
/* out-of-band data */
@ -623,22 +684,8 @@ int do_nand(cmd_tbl_t * cmdtp, int flag, int argc, char * const argv[])
ret = nand - > read_oob ( nand , off , & ops ) ;
else
ret = nand - > write_oob ( nand , off , & ops ) ;
} else if ( ! strcmp ( s , " .raw " ) ) {
/* Raw access */
mtd_oob_ops_t ops = {
. datbuf = ( u8 * ) addr ,
. oobbuf = ( ( u8 * ) addr ) + nand - > writesize ,
. len = nand - > writesize ,
. ooblen = nand - > oobsize ,
. mode = MTD_OOB_RAW
} ;
rwsize = nand - > writesize + nand - > oobsize ;
if ( read )
ret = nand - > read_oob ( nand , off , & ops ) ;
else
ret = nand - > write_oob ( nand , off , & ops ) ;
} else if ( raw ) {
ret = raw_access ( nand , addr , off , pagecount , read ) ;
} else {
printf ( " Unknown nand command suffix '%s'. \n " , s ) ;
return 1 ;
@ -732,9 +779,9 @@ U_BOOT_CMD(
" nand write - addr off|partition size \n "
" read/write 'size' bytes starting at offset 'off' \n "
" to/from memory address 'addr', skipping bad blocks. \n "
" nand read.raw - addr off|partition \n "
" nand write.raw - addr off|partition \n "
" Use read.raw/write.raw to avoid ECC and access the page as-is. \n "
" nand read.raw - addr off|partition [count] \n "
" nand write.raw - addr off|partition [count] \n "
" Use read.raw/write.raw to avoid ECC and access the flash as-is. \n "
# ifdef CONFIG_CMD_NAND_TRIMFFS
" nand write.trimffs - addr off|partition size \n "
" write 'size' bytes starting at offset 'off' from memory address \n "