@ -29,9 +29,10 @@
# include <watchdog.h>
flash_info_t flash_info [ CONFIG_SYS_MAX_FLASH_BANKS ] ; /* info for FLASH chips */
/* info for FLASH chips */
flash_info_t flash_info [ CONFIG_SYS_MAX_FLASH_BANKS ] ;
/*-----------------------------------------------------------------------
/*
* Functions
*/
static ulong flash_get_size ( vu_long * addr , flash_info_t * info ) ;
@ -39,9 +40,6 @@ static int write_word8(flash_info_t *info, ulong dest, ulong data);
static int write_word32 ( flash_info_t * info , ulong dest , ulong data ) ;
static void flash_get_offsets ( ulong base , flash_info_t * info ) ;
/*-----------------------------------------------------------------------
*/
unsigned long flash_init ( void )
{
int i ;
@ -49,18 +47,20 @@ unsigned long flash_init (void)
unsigned long size_b1 , base_b1 ;
/* Init: no FLASHes known */
for ( i = 0 ; i < CONFIG_SYS_MAX_FLASH_BANKS ; + + i ) {
for ( i = 0 ; i < CONFIG_SYS_MAX_FLASH_BANKS ; + + i )
flash_info [ i ] . flash_id = FLASH_UNKNOWN ;
}
/* Get Size of Boot and Main Flashes */
size_b0 = flash_get_size ( ( vu_long * ) FLASH_BASE0_PRELIM , & flash_info [ 0 ] ) ;
size_b0 = flash_get_size ( ( vu_long * ) FLASH_BASE0_PRELIM ,
& flash_info [ 0 ] ) ;
if ( flash_info [ 0 ] . flash_id = = FLASH_UNKNOWN ) {
printf ( " ## Unknown FLASH on Bank 0 - Size = 0x%08lx = %ld MB \n " ,
size_b0 , size_b0 < < 20 ) ;
return 0 ;
}
size_b1 = flash_get_size ( ( vu_long * ) FLASH_BASE1_PRELIM , & flash_info [ 1 ] ) ;
size_b1 =
flash_get_size ( ( vu_long * ) FLASH_BASE1_PRELIM ,
& flash_info [ 1 ] ) ;
if ( flash_info [ 1 ] . flash_id = = FLASH_UNKNOWN ) {
printf ( " ## Unknown FLASH on Bank 1 - Size = 0x%08lx = %ld MB \n " ,
size_b1 , size_b1 < < 20 ) ;
@ -77,36 +77,31 @@ unsigned long flash_init (void)
/* Protect board level data */
( void ) flash_protect ( FLAG_PROTECT_SET ,
base_b0 ,
flash_info [ 0 ] . start [ 1 ] - 1 ,
& flash_info [ 0 ] ) ;
flash_info [ 0 ] . start [ 1 ] - 1 , & flash_info [ 0 ] ) ;
/* Monitor protection ON by default */
( void ) flash_protect ( FLAG_PROTECT_SET ,
base_b0 + size_b0 - monitor_flash_len ,
base_b0 + size_b0 - 1 ,
& flash_info [ 0 ] ) ;
base_b0 + size_b0 - 1 , & flash_info [ 0 ] ) ;
/* Protect the FPGA image */
( void ) flash_protect ( FLAG_PROTECT_SET ,
FLASH_BASE1_PRELIM ,
FLASH_BASE1_PRELIM + CONFIG_SYS_FPGA_IMAGE_LEN - 1 ,
& flash_info [ 1 ] ) ;
FLASH_BASE1_PRELIM + CONFIG_SYS_FPGA_IMAGE_LEN -
1 , & flash_info [ 1 ] ) ;
/* Protect the default boot image */
( void ) flash_protect ( FLAG_PROTECT_SET ,
FLASH_BASE1_PRELIM + CONFIG_SYS_FPGA_IMAGE_LEN ,
FLASH_BASE1_PRELIM + CONFIG_SYS_FPGA_IMAGE_LEN + 0x600000 - 1 ,
& flash_info [ 1 ] ) ;
FLASH_BASE1_PRELIM + CONFIG_SYS_FPGA_IMAGE_LEN +
0x600000 - 1 , & flash_info [ 1 ] ) ;
/* Setup offsets for Main Flash */
flash_get_offsets ( FLASH_BASE1_PRELIM , & flash_info [ 1 ] ) ;
return ( size_b0 + size_b1 ) ;
} /* end flash_init() */
return size_b0 + size_b1 ;
}
/*-----------------------------------------------------------------------
*/
static void flash_get_offsets ( ulong base , flash_info_t * info )
{
int i ;
@ -118,8 +113,6 @@ static void flash_get_offsets (ulong base, flash_info_t *info)
}
} /* end flash_get_offsets() */
/*-----------------------------------------------------------------------
*/
void flash_print_info ( flash_info_t * info )
{
int i ;
@ -134,10 +127,17 @@ void flash_print_info (flash_info_t *info)
}
switch ( info - > flash_id & FLASH_VENDMASK ) {
case FLASH_MAN_AMD : printf ( " 1 x AMD " ) ; break ;
case FLASH_MAN_STM : printf ( " 1 x STM " ) ; break ;
case FLASH_MAN_INTEL : printf ( " 2 x Intel " ) ; break ;
default : printf ( " Unknown Vendor " ) ;
case FLASH_MAN_AMD :
printf ( " 1 x AMD " ) ;
break ;
case FLASH_MAN_STM :
printf ( " 1 x STM " ) ;
break ;
case FLASH_MAN_INTEL :
printf ( " 2 x Intel " ) ;
break ;
default :
printf ( " Unknown Vendor " ) ;
}
switch ( info - > flash_id & FLASH_TYPEMASK ) {
@ -182,10 +182,8 @@ void flash_print_info (flash_info_t *info)
erased = 1 ;
flash = ( volatile unsigned long * ) info - > start [ i ] ;
size = size > > 2 ; /* divide by 4 for longword access */
for ( k = 0 ; k < size ; k + + )
{
if ( * flash + + ! = 0xffffffff )
{
for ( k = 0 ; k < size ; k + + ) {
if ( * flash + + ! = 0xffffffff ) {
erased = 0 ;
break ;
}
@ -196,8 +194,7 @@ void flash_print_info (flash_info_t *info)
printf ( " %08lX%s%s " ,
info - > start [ i ] ,
erased ? " E " : " " ,
info - > protect [ i ] ? " RO " : " "
) ;
info - > protect [ i ] ? " RO " : " " ) ;
}
printf ( " \n " ) ;
} /* end flash_print_info() */
@ -252,8 +249,7 @@ static ulong flash_get_size (vu_long *addr, flash_info_t *info)
* addr2 = 0xf0 ; /* => no or unknown flash */
return 0 ;
}
}
else { /* MAIN Flash */
} else { /* MAIN Flash */
unsigned long value ;
volatile unsigned long * addr2 = ( unsigned long * ) addr ;
@ -311,30 +307,38 @@ static ulong flash_get_size (vu_long *addr, flash_info_t *info)
case FLASH_28F640J3A :
case FLASH_28F128J3A :
for ( i = 0 ; i < info - > sector_count ; i + + )
info - > start [ i ] = base + ( i * 0x00020000 * 2 ) ; /* 2 Banks */
info - > start [ i ] = base +
( i * 0x00020000 * 2 ) ; /* 2 Banks */
break ;
}
/* Test for Boot Flash */
if ( base = = FLASH_BASE0_PRELIM ) {
volatile unsigned char * addr2 ;
/* check for protected sectors */
for ( i = 0 ; i < info - > sector_count ; i + + ) {
/* read sector protection at sector address, (AX .. A0) = 0x02 */
/* D0 = 1 if protected */
/*
* read sector protection at sector address ,
* ( AX . . A0 ) = 0x02
* D0 = 1 if protected
*/
addr2 = ( volatile unsigned char * ) ( info - > start [ i ] ) ;
info - > protect [ i ] = * ( addr2 + 2 ) & 1 ;
}
/* Restore read mode */
* ( unsigned char * ) base = 0xF0 ; /* Reset NORMAL Flash */
}
else { /* Main Flash */
} else { /* Main Flash */
volatile unsigned long * addr2 ;
/* check for protected sectors */
for ( i = 0 ; i < info - > sector_count ; i + + ) {
/* read sector protection at sector address, (AX .. A0) = 0x02 */
/* D0 = 1 if protected */
/*
* read sector protection at sector address ,
* ( AX . . A0 ) = 0x02
* D0 = 1 if protected
*/
addr2 = ( volatile unsigned long * ) ( info - > start [ i ] ) ;
info - > protect [ i ] = * ( addr2 + 2 ) & 0x1 ;
}
@ -343,12 +347,9 @@ static ulong flash_get_size (vu_long *addr, flash_info_t *info)
* ( unsigned long * ) base = 0xFFFFFFFF ; /* Reset Flash */
}
return ( info - > size ) ;
return info - > size ;
} /* end flash_get_size() */
/*-----------------------------------------------------------------------
*/
static int wait_for_DQ7 ( ulong addr , uchar cmp_val , ulong tout )
{
int i ;
@ -361,9 +362,8 @@ static int wait_for_DQ7(ulong addr, uchar cmp_val, ulong tout)
/* Pause 10 us */
/* Check for completion */
if ( ( vaddr [ 0 ] & 0x80 ) = = ( cmp_val & 0x80 ) ) {
if ( ( vaddr [ 0 ] & 0x80 ) = = ( cmp_val & 0x80 ) )
return 0 ;
}
/* KEEP THE LUSER HAPPY - Print a dot every 1.1 seconds */
if ( ! ( i % 110000 ) )
@ -376,9 +376,6 @@ static int wait_for_DQ7(ulong addr, uchar cmp_val, ulong tout)
return 1 ;
} /* wait_for_DQ7() */
/*-----------------------------------------------------------------------
*/
static int flash_erase8 ( flash_info_t * info , int s_first , int s_last )
{
int tcode , rcode = 0 ;
@ -407,22 +404,25 @@ static int flash_erase8(flash_info_t *info, int s_first, int s_last)
if ( info - > protect [ sect ] )
prot + + ;
}
if ( prot )
printf ( " - Warning: %d protected sectors will not be erased! \n " , prot ) ;
else
if ( prot ) {
printf ( " - Warning: %d protected sectors will not be erased! \n " ,
prot ) ;
} else {
printf ( " \n " ) ;
}
/* Start erase on unprotected sectors */
for ( sect = s_first ; sect < = s_last ; sect + + ) {
if ( info - > protect [ sect ] = = 0 ) { /* not protected */
sector_addr = ( uchar * ) ( info - > start [ sect ] ) ;
if ( ( info - > flash_id & FLASH_VENDMASK ) = = FLASH_MAN_STM )
if ( ( info - > flash_id & FLASH_VENDMASK ) = =
FLASH_MAN_STM )
printf ( " Erasing block %p \n " , sector_addr ) ;
else
printf ( " Erasing sector %p \n " , sector_addr ) ;
/* Disable interrupts which might cause Flash to timeout */
/* Disable interrupts which might cause timeout */
flag = disable_interrupts ( ) ;
* ( addr + 0x555 ) = ( uchar ) 0xAA ;
@ -491,10 +491,12 @@ static int flash_erase32(flash_info_t *info, int s_first, int s_last)
if ( info - > protect [ sect ] )
prot + + ;
}
if ( prot )
printf ( " - Warning: %d protected sectors will not be erased! \n " , prot ) ;
else
if ( prot ) {
printf ( " - Warning: %d protected sectors will not be erased! \n " ,
prot ) ;
} else {
printf ( " \n " ) ;
}
start = get_timer ( 0 ) ;
last = start ;
@ -505,7 +507,7 @@ static int flash_erase32(flash_info_t *info, int s_first, int s_last)
vu_long * addr = ( vu_long * ) ( info - > start [ sect ] ) ;
unsigned long status ;
/* Disable interrupts which might cause a timeout here */
/* Disable interrupts which might cause a timeout */
flag = disable_interrupts ( ) ;
* addr = 0x00500050 ; /* clear status register */
@ -520,15 +522,21 @@ static int flash_erase32(flash_info_t *info, int s_first, int s_last)
udelay ( 1000 ) ;
while ( ( ( status = * addr ) & 0x00800080 ) ! = 0x00800080 ) {
if ( ( now = get_timer ( start ) ) > CONFIG_SYS_FLASH_ERASE_TOUT ) {
now = get_timer ( start ) ;
if ( now > CONFIG_SYS_FLASH_ERASE_TOUT ) {
printf ( " Timeout \n " ) ;
* addr = 0x00B000B0 ; /* suspend erase */
* addr = 0x00FF00FF ; /* reset to read mode */
/* suspend erase */
* addr = 0x00B000B0 ;
/* reset to read mode */
* addr = 0x00FF00FF ;
return 1 ;
}
/* show that we're waiting */
if ( ( now - last ) > 990 ) { /* every second */
/*
* show that we ' re waiting
* every second ( ? )
*/
if ( ( now - last ) > 990 ) {
putc ( ' . ' ) ;
last = now ;
}
@ -538,7 +546,7 @@ static int flash_erase32(flash_info_t *info, int s_first, int s_last)
}
printf ( " done \n " ) ;
return 0 ;
} /* end flash_erase32() */
}
int flash_erase ( flash_info_t * info , int s_first , int s_last )
{
@ -546,15 +554,16 @@ int flash_erase(flash_info_t *info, int s_first, int s_last)
return flash_erase8 ( info , s_first , s_last ) ;
else
return flash_erase32 ( info , s_first , s_last ) ;
} /* end flash_erase() */
}
/*-----------------------------------------------------------------------
/*
* Copy memory to flash , returns :
* 0 - OK
* 1 - write timeout
* 2 - Flash not erased
*/
static int write_buff8 ( flash_info_t * info , uchar * src , ulong addr , ulong cnt )
static int write_buff8 ( flash_info_t * info , uchar * src , ulong addr ,
ulong cnt )
{
ulong cp , wp , data ;
ulong start ;
@ -568,23 +577,25 @@ static int write_buff8(flash_info_t *info, uchar *src, ulong addr, ulong cnt)
/*
* handle unaligned start bytes
*/
if ( ( l = addr - wp ) ! = 0 ) {
l = addr - wp ;
if ( l ! = 0 ) {
data = 0 ;
for ( i = 0 , cp = wp ; i < l ; + + i , + + cp ) {
for ( i = 0 , cp = wp ; i < l ; + + i , + + cp )
data = ( data < < 8 ) | ( * ( uchar * ) cp ) ;
}
for ( ; i < 4 & & cnt > 0 ; + + i ) {
data = ( data < < 8 ) | * src + + ;
- - cnt ;
+ + cp ;
}
for ( ; cnt = = 0 & & i < 4 ; + + i , + + cp ) {
for ( ; cnt = = 0 & & i < 4 ; + + i , + + cp )
data = ( data < < 8 ) | ( * ( uchar * ) cp ) ;
}
if ( ( rc = write_word8 ( info , wp , data ) ) ! = 0 ) {
return ( rc ) ;
}
rc = write_word8 ( info , wp , data ) ;
if ( rc ! = 0 )
return rc ;
wp + = 4 ;
}
@ -593,12 +604,13 @@ static int write_buff8(flash_info_t *info, uchar *src, ulong addr, ulong cnt)
*/
while ( cnt > = 4 ) {
data = 0 ;
for ( i = 0 ; i < 4 ; + + i ) {
for ( i = 0 ; i < 4 ; + + i )
data = ( data < < 8 ) | * src + + ;
}
if ( ( rc = write_word8 ( info , wp , data ) ) ! = 0 ) {
return ( rc ) ;
}
rc = write_word8 ( info , wp , data ) ;
if ( rc ! = 0 )
return rc ;
wp + = 4 ;
cnt - = 4 ;
if ( get_timer ( start ) > 1000 ) { /* every second */
@ -608,9 +620,8 @@ static int write_buff8(flash_info_t *info, uchar *src, ulong addr, ulong cnt)
}
}
if ( cnt = = 0 ) {
return ( 0 ) ;
}
if ( cnt = = 0 )
return 0 ;
/*
* handle unaligned tail bytes
@ -620,15 +631,16 @@ static int write_buff8(flash_info_t *info, uchar *src, ulong addr, ulong cnt)
data = ( data < < 8 ) | * src + + ;
- - cnt ;
}
for ( ; i < 4 ; + + i , + + cp ) {
for ( ; i < 4 ; + + i , + + cp )
data = ( data < < 8 ) | ( * ( uchar * ) cp ) ;
}
return ( write_word8 ( info , wp , data ) ) ;
} /* end write_buff8() */
return write_word8 ( info , wp , data ) ;
}
# define FLASH_WIDTH 4 /* flash bus width in bytes */
static int write_buff32 ( flash_info_t * info , uchar * src , ulong addr , ulong cnt )
static int write_buff32 ( flash_info_t * info , uchar * src , ulong addr ,
ulong cnt )
{
ulong cp , wp , data ;
int i , l , rc ;
@ -636,32 +648,33 @@ static int write_buff32 (flash_info_t *info, uchar *src, ulong addr, ulong cnt)
start = get_timer ( 0 ) ;
if ( info - > flash_id = = FLASH_UNKNOWN ) {
if ( info - > flash_id = = FLASH_UNKNOWN )
return 4 ;
}
wp = ( addr & ~ ( FLASH_WIDTH - 1 ) ) ; /* get lower FLASH_WIDTH aligned address */
/* get lower FLASH_WIDTH aligned address */
wp = ( addr & ~ ( FLASH_WIDTH - 1 ) ) ;
/*
* handle unaligned start bytes
*/
if ( ( l = addr - wp ) ! = 0 ) {
data = 0 ;
for ( i = 0 , cp = wp ; i < l ; + + i , + + cp ) {
for ( i = 0 , cp = wp ; i < l ; + + i , + + cp )
data = ( data < < 8 ) | ( * ( uchar * ) cp ) ;
}
for ( ; i < FLASH_WIDTH & & cnt > 0 ; + + i ) {
data = ( data < < 8 ) | * src + + ;
- - cnt ;
+ + cp ;
}
for ( ; cnt = = 0 & & i < FLASH_WIDTH ; + + i , + + cp ) {
for ( ; cnt = = 0 & & i < FLASH_WIDTH ; + + i , + + cp )
data = ( data < < 8 ) | ( * ( uchar * ) cp ) ;
}
if ( ( rc = write_word32 ( info , wp , data ) ) ! = 0 ) {
return ( rc ) ;
}
rc = write_word32 ( info , wp , data ) ;
if ( rc ! = 0 )
return rc ;
wp + = FLASH_WIDTH ;
}
@ -670,12 +683,13 @@ static int write_buff32 (flash_info_t *info, uchar *src, ulong addr, ulong cnt)
*/
while ( cnt > = FLASH_WIDTH ) {
data = 0 ;
for ( i = 0 ; i < FLASH_WIDTH ; + + i ) {
for ( i = 0 ; i < FLASH_WIDTH ; + + i )
data = ( data < < 8 ) | * src + + ;
}
if ( ( rc = write_word32 ( info , wp , data ) ) ! = 0 ) {
return ( rc ) ;
}
rc = write_word32 ( info , wp , data ) ;
if ( rc ! = 0 )
return rc ;
wp + = FLASH_WIDTH ;
cnt - = FLASH_WIDTH ;
if ( get_timer ( start ) > 990 ) { /* every second */
@ -684,9 +698,8 @@ static int write_buff32 (flash_info_t *info, uchar *src, ulong addr, ulong cnt)
}
}
if ( cnt = = 0 ) {
return ( 0 ) ;
}
if ( cnt = = 0 )
return 0 ;
/*
* handle unaligned tail bytes
@ -696,12 +709,12 @@ static int write_buff32 (flash_info_t *info, uchar *src, ulong addr, ulong cnt)
data = ( data < < 8 ) | * src + + ;
- - cnt ;
}
for ( ; i < FLASH_WIDTH ; + + i , + + cp ) {
for ( ; i < FLASH_WIDTH ; + + i , + + cp )
data = ( data < < 8 ) | ( * ( uchar * ) cp ) ;
}
return ( write_word32 ( info , wp , data ) ) ;
} /* write_buff32() */
return write_word32 ( info , wp , data ) ;
}
int write_buff ( flash_info_t * info , uchar * src , ulong addr , ulong cnt )
{
@ -713,9 +726,9 @@ int write_buff(flash_info_t *info, uchar *src, ulong addr, ulong cnt)
retval = write_buff32 ( info , src , addr , cnt ) ;
return retval ;
} /* end write_buff() */
}
/*-----------------------------------------------------------------------
/*
* Write a word to Flash , returns :
* 0 - OK
* 1 - write timeout
@ -731,10 +744,8 @@ static int write_word8(flash_info_t *info, ulong dest, ulong data)
int i , tcode , rcode = 0 ;
/* Check if Flash is (sufficently) erased */
if ( ( * ( ( volatile uchar * ) dest ) &
( uchar ) data ) ! = ( uchar ) data ) {
return ( 2 ) ;
}
if ( ( * ( ( volatile uchar * ) dest ) & ( uchar ) data ) ! = ( uchar ) data )
return 2 ;
for ( i = 0 ; i < ( 4 / sizeof ( uchar ) ) ; i + + ) {
/* Disable interrupts which might cause a timeout here */
@ -754,13 +765,12 @@ static int write_word8(flash_info_t *info, ulong dest, ulong data)
enable_interrupts ( ) ;
/* Make sure we didn't timeout */
if ( tcode ) {
if ( tcode )
rcode = 1 ;
}
}
return rcode ;
} /* end write_word8() */
}
static int write_word32 ( flash_info_t * info , ulong dest , ulong data )
{
@ -770,9 +780,9 @@ static int write_word32(flash_info_t *info, ulong dest, ulong data)
int flag ;
/* Check if Flash is (sufficiently) erased */
if ( ( * addr & data ) ! = data ) {
return ( 2 ) ;
}
if ( ( * addr & data ) ! = data )
return 2 ;
/* Disable interrupts which might cause a timeout here */
flag = disable_interrupts ( ) ;
@ -789,15 +799,14 @@ static int write_word32(flash_info_t *info, ulong dest, ulong data)
WATCHDOG_RESET ( ) ;
if ( get_timer ( start ) > CONFIG_SYS_FLASH_WRITE_TOUT ) {
* addr = 0x00FF00FF ; /* restore read mode */
return ( 1 ) ;
return 1 ;
}
}
* addr = 0x00FF00FF ; /* restore read mode */
return ( 0 ) ;
} /* end write_word32() */
return 0 ;
}
static int _flash_protect ( flash_info_t * info , long sector )
{
@ -855,7 +864,7 @@ static int _flash_protect(flash_info_t *info, long sector)
}
return rcode ;
} /* end _flash_protect() */
}
static int _flash_unprotect ( flash_info_t * info , long sector )
{
@ -915,14 +924,12 @@ static int _flash_unprotect(flash_info_t *info, long sector)
if ( _flash_protect ( info , info - > start [ i ] ) )
rcode = 1 ;
}
}
else /* Turn protection off for this sector */
} else /* Turn protection off for this sector */
info - > protect [ i ] = 0 ;
}
return rcode ;
} /* end _flash_unprotect() */
}
int flash_real_protect ( flash_info_t * info , long sector , int prot )
{
@ -934,7 +941,4 @@ int flash_real_protect(flash_info_t *info, long sector, int prot)
rcode = _flash_unprotect ( info , info - > start [ sector ] ) ;
return rcode ;
} /* end flash_real_protect() */
/*-----------------------------------------------------------------------
*/
}