@ -1302,13 +1302,105 @@ void flash_read_factory_serial (flash_info_t * info, void *buffer, int offset,
# endif /* CFG_FLASH_PROTECTION */
/*-----------------------------------------------------------------------
* Reverse the order of the erase regions in the CFI QRY structure .
* This is needed for chips that are either a ) correctly detected as
* top - boot , or b ) buggy .
*/
static void cfi_reverse_geometry ( struct cfi_qry * qry )
{
unsigned int i , j ;
u32 tmp ;
for ( i = 0 , j = qry - > num_erase_regions - 1 ; i < j ; i + + , j - - ) {
tmp = qry - > erase_region_info [ i ] ;
qry - > erase_region_info [ i ] = qry - > erase_region_info [ j ] ;
qry - > erase_region_info [ j ] = tmp ;
}
}
/*-----------------------------------------------------------------------
* read jedec ids from device and set corresponding fields in info struct
*
* Note : assume cfi - > vendor , cfi - > portwidth and cfi - > chipwidth are correct
*
*/
*/
static void cmdset_intel_read_jedec_ids ( flash_info_t * info )
{
flash_write_cmd ( info , 0 , 0 , FLASH_CMD_RESET ) ;
flash_write_cmd ( info , 0 , 0 , FLASH_CMD_READ_ID ) ;
udelay ( 1000 ) ; /* some flash are slow to respond */
info - > manufacturer_id = flash_read_uchar ( info ,
FLASH_OFFSET_MANUFACTURER_ID ) ;
info - > device_id = flash_read_uchar ( info ,
FLASH_OFFSET_DEVICE_ID ) ;
flash_write_cmd ( info , 0 , 0 , FLASH_CMD_RESET ) ;
}
static int cmdset_intel_init ( flash_info_t * info , struct cfi_qry * qry )
{
info - > cmd_reset = FLASH_CMD_RESET ;
cmdset_intel_read_jedec_ids ( info ) ;
flash_write_cmd ( info , 0 , info - > cfi_offset , FLASH_CMD_CFI ) ;
# ifdef CFG_FLASH_PROTECTION
/* read legacy lock/unlock bit from intel flash */
if ( info - > ext_addr ) {
info - > legacy_unlock = flash_read_uchar ( info ,
info - > ext_addr + 5 ) & 0x08 ;
}
# endif
return 0 ;
}
static void cmdset_amd_read_jedec_ids ( flash_info_t * info )
{
flash_write_cmd ( info , 0 , 0 , AMD_CMD_RESET ) ;
flash_unlock_seq ( info , 0 ) ;
flash_write_cmd ( info , 0 , info - > addr_unlock1 , FLASH_CMD_READ_ID ) ;
udelay ( 1000 ) ; /* some flash are slow to respond */
info - > manufacturer_id = flash_read_uchar ( info ,
FLASH_OFFSET_MANUFACTURER_ID ) ;
info - > device_id = flash_read_uchar ( info ,
FLASH_OFFSET_DEVICE_ID ) ;
if ( info - > device_id = = 0x7E ) {
/* AMD 3-byte (expanded) device ids */
info - > device_id2 = flash_read_uchar ( info ,
FLASH_OFFSET_DEVICE_ID2 ) ;
info - > device_id2 < < = 8 ;
info - > device_id2 | = flash_read_uchar ( info ,
FLASH_OFFSET_DEVICE_ID3 ) ;
}
flash_write_cmd ( info , 0 , 0 , AMD_CMD_RESET ) ;
}
static int cmdset_amd_init ( flash_info_t * info , struct cfi_qry * qry )
{
info - > cmd_reset = AMD_CMD_RESET ;
cmdset_amd_read_jedec_ids ( info ) ;
flash_write_cmd ( info , 0 , info - > cfi_offset , FLASH_CMD_CFI ) ;
/* check if flash geometry needs reversal */
if ( qry - > num_erase_regions > 1 ) {
/* reverse geometry if top boot part */
if ( info - > cfi_version < 0x3131 ) {
/* CFI < 1.1, try to guess from device id */
if ( ( info - > device_id & 0x80 ) ! = 0 )
cfi_reverse_geometry ( qry ) ;
} else if ( flash_read_uchar ( info , info - > ext_addr + 0xf ) = = 3 ) {
/* CFI >= 1.1, deduct from top/bottom flag */
/* note: ext_addr is valid since cfi_version > 0 */
cfi_reverse_geometry ( qry ) ;
}
}
return 0 ;
}
# ifdef CONFIG_FLASH_CFI_LEGACY
static void flash_read_jedec_ids ( flash_info_t * info )
{
info - > manufacturer_id = 0 ;
@ -1318,41 +1410,17 @@ static void flash_read_jedec_ids (flash_info_t * info)
switch ( info - > vendor ) {
case CFI_CMDSET_INTEL_STANDARD :
case CFI_CMDSET_INTEL_EXTENDED :
flash_write_cmd ( info , 0 , 0 , FLASH_CMD_RESET ) ;
flash_write_cmd ( info , 0 , 0 , FLASH_CMD_READ_ID ) ;
udelay ( 1000 ) ; /* some flash are slow to respond */
info - > manufacturer_id = flash_read_uchar ( info ,
FLASH_OFFSET_MANUFACTURER_ID ) ;
info - > device_id = flash_read_uchar ( info ,
FLASH_OFFSET_DEVICE_ID ) ;
flash_write_cmd ( info , 0 , 0 , FLASH_CMD_RESET ) ;
flash_read_jedec_ids_intel ( info ) ;
break ;
case CFI_CMDSET_AMD_STANDARD :
case CFI_CMDSET_AMD_EXTENDED :
flash_write_cmd ( info , 0 , 0 , AMD_CMD_RESET ) ;
flash_unlock_seq ( info , 0 ) ;
flash_write_cmd ( info , 0 , info - > addr_unlock1 , FLASH_CMD_READ_ID ) ;
udelay ( 1000 ) ; /* some flash are slow to respond */
info - > manufacturer_id = flash_read_uchar ( info ,
FLASH_OFFSET_MANUFACTURER_ID ) ;
info - > device_id = flash_read_uchar ( info ,
FLASH_OFFSET_DEVICE_ID ) ;
if ( info - > device_id = = 0x7E ) {
/* AMD 3-byte (expanded) device ids */
info - > device_id2 = flash_read_uchar ( info ,
FLASH_OFFSET_DEVICE_ID2 ) ;
info - > device_id2 < < = 8 ;
info - > device_id2 | = flash_read_uchar ( info ,
FLASH_OFFSET_DEVICE_ID3 ) ;
}
flash_write_cmd ( info , 0 , 0 , AMD_CMD_RESET ) ;
flash_read_jedec_ids_amd ( info ) ;
break ;
default :
break ;
}
}
# ifdef CONFIG_FLASH_CFI_LEGACY
/*-----------------------------------------------------------------------
* Call board code to request info about non - CFI flash .
* board_flash_get_legacy needs to fill in at least :
@ -1514,7 +1582,6 @@ ulong flash_get_size (ulong base, int banknum)
uchar num_erase_regions ;
int erase_region_size ;
int erase_region_count ;
int geometry_reversed = 0 ;
struct cfi_qry qry ;
info - > ext_addr = 0 ;
@ -1530,51 +1597,36 @@ ulong flash_get_size (ulong base, int banknum)
info - > ext_addr = le16_to_cpu ( qry . p_adr ) ;
num_erase_regions = qry . num_erase_regions ;
flash_read_jedec_ids ( info ) ;
flash_write_cmd ( info , 0 , info - > cfi_offset , FLASH_CMD_CFI ) ;
if ( info - > ext_addr ) {
info - > cfi_version = ( ushort ) flash_read_uchar ( info ,
info - > ext_addr + 3 ) < < 8 ;
info - > cfi_version | = ( ushort ) flash_read_uchar ( info ,
info - > ext_addr + 4 ) ;
}
# ifdef DEBUG
flash_printqry ( & qry ) ;
# endif
switch ( info - > vendor ) {
case CFI_CMDSET_INTEL_STANDARD :
case CFI_CMDSET_INTEL_EXTENDED :
default :
info - > cmd_reset = FLASH_CMD_RESET ;
# ifdef CFG_FLASH_PROTECTION
/* read legacy lock/unlock bit from intel flash */
if ( info - > ext_addr ) {
info - > legacy_unlock = flash_read_uchar ( info ,
info - > ext_addr + 5 ) & 0x08 ;
}
# endif
cmdset_intel_init ( info , & qry ) ;
break ;
case CFI_CMDSET_AMD_STANDARD :
case CFI_CMDSET_AMD_EXTENDED :
info - > cmd_reset = AMD_CMD_RESET ;
/* check if flash geometry needs reversal */
if ( num_erase_regions < = 1 )
break ;
/* reverse geometry if top boot part */
if ( info - > cfi_version < 0x3131 ) {
/* CFI < 1.1, try to guess from device id */
if ( ( info - > device_id & 0x80 ) ! = 0 ) {
geometry_reversed = 1 ;
}
break ;
}
/* CFI >= 1.1, deduct from top/bottom flag */
/* note: ext_addr is valid since cfi_version > 0 */
if ( flash_read_uchar ( info , info - > ext_addr + 0xf ) = = 3 ) {
geometry_reversed = 1 ;
}
cmdset_amd_init ( info , & qry ) ;
break ;
default :
printf ( " CFI: Unknown command set 0x%x \n " ,
info - > vendor ) ;
/*
* Unfortunately , this means we don ' t know how
* to get the chip back to Read mode . Might
* as well try an Intel - style reset . . .
*/
flash_write_cmd ( info , 0 , 0 , FLASH_CMD_RESET ) ;
return 0 ;
}
debug ( " manufacturer is %d \n " , info - > vendor ) ;
@ -1596,18 +1648,14 @@ ulong flash_get_size (ulong base, int banknum)
sect_cnt = 0 ;
sector = base ;
for ( i = 0 ; i < num_erase_regions ; i + + ) {
unsigned int region = i ;
if ( i > NUM_ERASE_REGIONS ) {
printf ( " %d erase regions found, only %d used \n " ,
num_erase_regions , NUM_ERASE_REGIONS ) ;
break ;
}
if ( geometry_reversed )
region = num_erase_regions - 1 - i ;
tmp = le32_to_cpu ( qry . erase_region_info [ reg ion ] ) ;
debug ( " erase region %u: 0x%08lx \n " , reg ion , tmp ) ;
tmp = le32_to_cpu ( qry . erase_region_info [ i ] ) ;
debug ( " erase region %u: 0x%08lx \n " , i , tmp ) ;
erase_region_count = ( tmp & 0xffff ) + 1 ;
tmp > > = 16 ;