From ca7f54ec8a5b7e7b9aefd35961c92c84cc31c503 Mon Sep 17 00:00:00 2001 From: save Date: Thu, 6 May 2010 15:31:59 +0000 Subject: cleo/u-boot: force unprotect during init for atmel flashs (on SCR310) git-svn-id: svn+ssh://pessac/svn/cesar/trunk@7002 017c9cb6-072f-447c-8318-d5b54f68fe89 --- cleopatre/u-boot-1.1.6/board/sdk300/flash.c | 96 +++++++++++++++++------------ 1 file changed, 56 insertions(+), 40 deletions(-) (limited to 'cleopatre') diff --git a/cleopatre/u-boot-1.1.6/board/sdk300/flash.c b/cleopatre/u-boot-1.1.6/board/sdk300/flash.c index f4e4895ba2..584a89fe18 100644 --- a/cleopatre/u-boot-1.1.6/board/sdk300/flash.c +++ b/cleopatre/u-boot-1.1.6/board/sdk300/flash.c @@ -41,6 +41,8 @@ typedef struct OrgDef flash_info_t flash_info[CFG_MAX_FLASH_BANKS]; /* info for FLASH chips */ +#define IS_ATMEL_FLASH(id) (((id) & 0x00FF0000) == 0x1F0000) + /* OPCODES (all one byte long for Spansion S25FL064A SPI Flash */ /* write */ @@ -107,6 +109,7 @@ int ERROR_FLASH_SPI = 0; int flash_read_status_spi(unsigned char *flash_spi_status); int flash_read_id_spi(unsigned int *flash_spi_id); +int flash_real_protect (flash_info_t * info, long sector, int prot); /* --- Utility functions --- */ static inline void swap_endians (int *in) @@ -252,10 +255,11 @@ void init_spi_controller(void) int flash_read_id_spi(unsigned int *flash_spi_id) { int rc = ERR_OK; + int i; /* poll until Tx and Rx FIFOs are empty and SPI bus is not busy - to be sure that no other transmissoin is in progress */ + to be sure that no other transmission is in progress */ if ( ( rc = wait_status(WAIT_ALL_FIFO_EMPTY_AND_NOT_BUSY) != ERR_OK ) ) { return rc; @@ -263,19 +267,21 @@ int flash_read_id_spi(unsigned int *flash_spi_id) /* read spi flash status reg */ SPI_CTL_CONF_TX = 0x00010008; /* send one byte */ - SPI_CTL_CONF_RX = 0x00010018; /* receive 3 bytes */ + SPI_CTL_CONF_RX = 0x00030008; /* receive 3 bytes */ /*issue the command to spi flash */ SPI_CTL_TX_REG = RDID; - /* busy wait for RECEIVED_WORD bit in status reg */ - if ( ( rc = wait_status(WAIT_RECEIVED_WORD) != ERR_OK ) ) + /* flash spi status is now in SPI Controller Rx reg */ + *flash_spi_id = 0; + for (i=0; i<3; i++) { - return rc; + if ( ( rc = wait_status(WAIT_RX_FIFO_NOT_EMPTY) ) == ERR_TIMOUT ) + { + return rc; + } + *flash_spi_id = (*flash_spi_id << 8) | (SPI_CTL_RX_REG & 0xFF); } - /* flash spi status is now in SPI Controller Rx reg */ - *flash_spi_id = SPI_CTL_RX_REG; - return rc; } @@ -332,8 +338,13 @@ ulong flash_init (void) flash_nb_blocks = sizeof (OrgSPIFlash) / sizeof (OrgDef); flash_info[i].sector_count = flash_number_sector_spi(pOrgDef, flash_nb_blocks); + flash_read_id_spi (&flash_info[i].flash_id); memset (flash_info[i].protect, 0, flash_info[i].sector_count); + /* force unprotect for atmel flashs */ + if (IS_ATMEL_FLASH(flash_info[i].flash_id)) + flash_real_protect (&flash_info[i], 0, 0); + if (i == 0) flashbase = PHYS_FLASH_SPI_1; else @@ -370,7 +381,7 @@ void flash_print_info (flash_info_t * info) { int i; - printf ("FLASH SPI"); + printf ("FLASH SPI (Jedec=%#x)", info->flash_id); printf (" Size: %ld MB in %d Sectors\n", info->size >> 20, info->sector_count); @@ -708,42 +719,47 @@ int flash_real_protect (flash_info_t * info, long sector, int prot) int i; unsigned short protect_command; - /* before erase we have to write-enable SPI flash */ - if ( flash_write_enable_spi() == ERR_TIMOUT ) - { - printf ("Cannot write-enable SPI flash.\n"); - seterr_flash_spi(ERR_TIMOUT); - rc = ERR_TIMOUT; - return rc; - } - /* protection is done on all the flash */ - /* poll until Tx FIFO is empty - and SPI bus is not busy - to be sure that no other transmissions are in progress */ - if ( ( rc = wait_status(WAIT_TX_FIFO_EMPTY_AND_NOT_BUSY) != ERR_OK ) ) + if (IS_ATMEL_FLASH(info->flash_id)) { - return rc; - } + /* before erase we have to write-enable SPI flash */ + if ( flash_write_enable_spi() == ERR_TIMOUT ) + { + printf ("Cannot write-enable SPI flash.\n"); + seterr_flash_spi(ERR_TIMOUT); + rc = ERR_TIMOUT; + return rc; + } + /* protection is done on all the flash */ + /* poll until Tx FIFO is empty + and SPI bus is not busy + to be sure that no other transmissions are in progress */ + if ( ( rc = wait_status(WAIT_TX_FIFO_EMPTY_AND_NOT_BUSY) != ERR_OK ) ) + { + return rc; + } - protect_command = ((prot ? 0x3f : 0x00) << 8) | WRSR; - /* start command SPI controller seqence */ - SPI_CTL_CONF_TX = 0x00010010; /* send 32 bit message (command + address) */ - /* reset SPI_CTL_CONF_RX - no bytes expected to be received. - This step is needed because it will not be - auto-reset from the previous operaton */ - SPI_CTL_CONF_RX = 0x00000000; - /*issue the command to spi flash */ - SPI_CTL_TX_REG = protect_command; /* send protect */ - if ( ( rc = wait_status(WAIT_TX_FIFO_EMPTY_AND_NOT_BUSY) != ERR_OK ) ) - { - return rc; - } + protect_command = ((prot ? 0x3f : 0x00) << 8) | WRSR; + /* start command SPI controller seqence */ + SPI_CTL_CONF_TX = 0x00010010; /* send 32 bit message (command + address) */ + /* reset SPI_CTL_CONF_RX - no bytes expected to be received. + This step is needed because it will not be + auto-reset from the previous operaton */ + SPI_CTL_CONF_RX = 0x00000000; + /*issue the command to spi flash */ + SPI_CTL_TX_REG = protect_command; /* send protect */ + if ( ( rc = wait_status(WAIT_TX_FIFO_EMPTY_AND_NOT_BUSY) != ERR_OK ) ) + { + return rc; + } - /* protect on/off is put on all the flash */ - for (i = 0; i < info->sector_count; i++) { - info->protect[i] = prot; + /* protect on/off is put on all the flash */ + for (i = 0; i < info->sector_count; i++) { + info->protect[i] = prot; + } } + info->protect[sector] = prot; + return rc; } -- cgit v1.2.3