diff options
Diffstat (limited to 'board/bf537-stamp/stm_m25p64.c')
-rw-r--r-- | board/bf537-stamp/stm_m25p64.c | 516 |
1 files changed, 0 insertions, 516 deletions
diff --git a/board/bf537-stamp/stm_m25p64.c b/board/bf537-stamp/stm_m25p64.c deleted file mode 100644 index c48c3c7..0000000 --- a/board/bf537-stamp/stm_m25p64.c +++ /dev/null @@ -1,516 +0,0 @@ -/**************************************************************************** - * SPI flash driver for M25P64 - ****************************************************************************/ -#include <common.h> -#include <linux/ctype.h> -#include <asm/io.h> -#include <asm/mach-common/bits/spi.h> - -#if defined(CONFIG_SPI) - -/* Application definitions */ - -#define NUM_SECTORS 128 /* number of sectors */ -#define SECTOR_SIZE 0x10000 -#define NOP_NUM 1000 - -#define COMMON_SPI_SETTINGS (SPE|MSTR|CPHA|CPOL) /* Settings to the SPI_CTL */ -#define TIMOD01 (0x01) /* stes the SPI to work with core instructions */ - -/* Flash commands */ -#define SPI_WREN (0x06) /*Set Write Enable Latch */ -#define SPI_WRDI (0x04) /*Reset Write Enable Latch */ -#define SPI_RDSR (0x05) /*Read Status Register */ -#define SPI_WRSR (0x01) /*Write Status Register */ -#define SPI_READ (0x03) /*Read data from memory */ -#define SPI_FAST_READ (0x0B) /*Read data from memory */ -#define SPI_PP (0x02) /*Program Data into memory */ -#define SPI_SE (0xD8) /*Erase one sector in memory */ -#define SPI_BE (0xC7) /*Erase all memory */ -#define WIP (0x1) /*Check the write in progress bit of the SPI status register */ -#define WEL (0x2) /*Check the write enable bit of the SPI status register */ - -#define TIMEOUT 350000000 - -typedef enum { - NO_ERR, - POLL_TIMEOUT, - INVALID_SECTOR, - INVALID_BLOCK, -} ERROR_CODE; - -void spi_init_f(void); -void spi_init_r(void); -ssize_t spi_read(uchar *, int, uchar *, int); -ssize_t spi_write(uchar *, int, uchar *, int); - -char ReadStatusRegister(void); -void Wait_For_SPIF(void); -void SetupSPI(const int spi_setting); -void SPI_OFF(void); -void SendSingleCommand(const int iCommand); - -ERROR_CODE GetSectorNumber(unsigned long ulOffset, int *pnSector); -ERROR_CODE EraseBlock(int nBlock); -ERROR_CODE ReadData(unsigned long ulStart, long lCount, int *pnData); -ERROR_CODE WriteData(unsigned long ulStart, long lCount, int *pnData); -ERROR_CODE Wait_For_Status(char Statusbit); -ERROR_CODE Wait_For_WEL(void); - -/* - * Function: spi_init_f - * Description: Init SPI-Controller (ROM part) - * return: --- - */ -void spi_init_f(void) -{ -} - -/* - * Function: spi_init_r - * Description: Init SPI-Controller (RAM part) - - * The malloc engine is ready and we can move our buffers to - * normal RAM - * return: --- - */ -void spi_init_r(void) -{ - return; -} - -/* - * Function: spi_write - */ -ssize_t spi_write(uchar * addr, int alen, uchar * buffer, int len) -{ - unsigned long offset; - int start_block, end_block; - int start_byte, end_byte; - ERROR_CODE result = NO_ERR; - uchar temp[SECTOR_SIZE]; - int i, num; - - offset = addr[0] << 16 | addr[1] << 8 | addr[2]; - /* Get the start block number */ - result = GetSectorNumber(offset, &start_block); - if (result == INVALID_SECTOR) { - printf("Invalid sector! "); - return 0; - } - /* Get the end block number */ - result = GetSectorNumber(offset + len - 1, &end_block); - if (result == INVALID_SECTOR) { - printf("Invalid sector! "); - return 0; - } - - for (num = start_block; num <= end_block; num++) { - ReadData(num * SECTOR_SIZE, SECTOR_SIZE, (int *)temp); - start_byte = num * SECTOR_SIZE; - end_byte = (num + 1) * SECTOR_SIZE - 1; - if (start_byte < offset) - start_byte = offset; - if (end_byte > (offset + len)) - end_byte = (offset + len - 1); - for (i = start_byte; i <= end_byte; i++) - temp[i - num * SECTOR_SIZE] = buffer[i - offset]; - EraseBlock(num); - result = WriteData(num * SECTOR_SIZE, SECTOR_SIZE, (int *)temp); - if (result != NO_ERR) - return 0; - printf("."); - } - return len; -} - -/* - * Function: spi_read - */ -ssize_t spi_read(uchar * addr, int alen, uchar * buffer, int len) -{ - unsigned long offset; - offset = addr[0] << 16 | addr[1] << 8 | addr[2]; - ReadData(offset, len, (int *)buffer); - return len; -} - -void SendSingleCommand(const int iCommand) -{ - unsigned short dummy; - - /* turns on the SPI in single write mode */ - SetupSPI((COMMON_SPI_SETTINGS | TIMOD01)); - - /* sends the actual command to the SPI TX register */ - *pSPI_TDBR = iCommand; - SSYNC(); - - /* The SPI status register will be polled to check the SPIF bit */ - Wait_For_SPIF(); - - dummy = *pSPI_RDBR; - - /* The SPI will be turned off */ - SPI_OFF(); - -} - -void SetupSPI(const int spi_setting) -{ - - if (icache_status() || dcache_status()) - udelay(CONFIG_CCLK_HZ / 50000000); - /*sets up the PF10 to be the slave select of the SPI */ - *pPORTF_FER |= (PF10 | PF11 | PF12 | PF13); - *pSPI_FLG = 0xFF02; - *pSPI_BAUD = CONFIG_SPI_BAUD; - *pSPI_CTL = spi_setting; - SSYNC(); - - *pSPI_FLG = 0xFD02; - SSYNC(); -} - -void SPI_OFF(void) -{ - - *pSPI_CTL = 0x0400; /* disable SPI */ - *pSPI_FLG = 0; - *pSPI_BAUD = 0; - SSYNC(); - udelay(CONFIG_CCLK_HZ / 50000000); - -} - -void Wait_For_SPIF(void) -{ - unsigned short dummyread; - while ((*pSPI_STAT & TXS)) ; - while (!(*pSPI_STAT & SPIF)) ; - while (!(*pSPI_STAT & RXS)) ; - /* Read dummy to empty the receive register */ - dummyread = *pSPI_RDBR; -} - -ERROR_CODE Wait_For_WEL(void) -{ - int i; - char status_register = 0; - ERROR_CODE ErrorCode = NO_ERR; - - for (i = 0; i < TIMEOUT; i++) { - status_register = ReadStatusRegister(); - if ((status_register & WEL)) { - ErrorCode = NO_ERR; - break; - } - ErrorCode = POLL_TIMEOUT; /* Time out error */ - }; - - return ErrorCode; -} - -ERROR_CODE Wait_For_Status(char Statusbit) -{ - int i; - char status_register = 0xFF; - ERROR_CODE ErrorCode = NO_ERR; - - for (i = 0; i < TIMEOUT; i++) { - status_register = ReadStatusRegister(); - if (!(status_register & Statusbit)) { - ErrorCode = NO_ERR; - break; - } - ErrorCode = POLL_TIMEOUT; /* Time out error */ - }; - - return ErrorCode; -} - -char ReadStatusRegister(void) -{ - char status_register = 0; - - SetupSPI((COMMON_SPI_SETTINGS | TIMOD01)); /* Turn on the SPI */ - - *pSPI_TDBR = SPI_RDSR; /* send instruction to read status register */ - SSYNC(); - Wait_For_SPIF(); /*wait until the instruction has been sent */ - *pSPI_TDBR = 0; /*send dummy to receive the status register */ - SSYNC(); - Wait_For_SPIF(); /*wait until the data has been sent */ - status_register = *pSPI_RDBR; /*read the status register */ - - SPI_OFF(); /* Turn off the SPI */ - - return status_register; -} - -ERROR_CODE GetSectorNumber(unsigned long ulOffset, int *pnSector) -{ - int nSector = 0; - ERROR_CODE ErrorCode = NO_ERR; - - if (ulOffset > (NUM_SECTORS * 0x10000 - 1)) { - ErrorCode = INVALID_SECTOR; - return ErrorCode; - } - - nSector = (int)ulOffset / 0x10000; - *pnSector = nSector; - - return ErrorCode; -} - -ERROR_CODE EraseBlock(int nBlock) -{ - unsigned long ulSectorOff = 0x0, ShiftValue; - ERROR_CODE ErrorCode = NO_ERR; - - /* if the block is invalid just return */ - if ((nBlock < 0) || (nBlock > NUM_SECTORS)) { - ErrorCode = INVALID_BLOCK; - return ErrorCode; - } - /* figure out the offset of the block in flash */ - if ((nBlock >= 0) && (nBlock < NUM_SECTORS)) { - ulSectorOff = (nBlock * SECTOR_SIZE); - - } else { - ErrorCode = INVALID_BLOCK; - return ErrorCode; - } - - /* A write enable instruction must previously have been executed */ - SendSingleCommand(SPI_WREN); - - /* The status register will be polled to check the write enable latch "WREN" */ - ErrorCode = Wait_For_WEL(); - - if (POLL_TIMEOUT == ErrorCode) { - printf("SPI Erase block error\n"); - return ErrorCode; - } else - - /* Turn on the SPI to send single commands */ - SetupSPI((COMMON_SPI_SETTINGS | TIMOD01)); - - /* - * Send the erase block command to the flash followed by the 24 address - * to point to the start of a sector - */ - *pSPI_TDBR = SPI_SE; - SSYNC(); - Wait_For_SPIF(); - /* Send the highest byte of the 24 bit address at first */ - ShiftValue = (ulSectorOff >> 16); - *pSPI_TDBR = ShiftValue; - SSYNC(); - /* Wait until the instruction has been sent */ - Wait_For_SPIF(); - /* Send the middle byte of the 24 bit address at second */ - ShiftValue = (ulSectorOff >> 8); - *pSPI_TDBR = ShiftValue; - SSYNC(); - /* Wait until the instruction has been sent */ - Wait_For_SPIF(); - /* Send the lowest byte of the 24 bit address finally */ - *pSPI_TDBR = ulSectorOff; - SSYNC(); - /* Wait until the instruction has been sent */ - Wait_For_SPIF(); - - /* Turns off the SPI */ - SPI_OFF(); - - /* Poll the status register to check the Write in Progress bit */ - /* Sector erase takes time */ - ErrorCode = Wait_For_Status(WIP); - - /* block erase should be complete */ - return ErrorCode; -} - -/* - * ERROR_CODE ReadData() - * Read a value from flash for verify purpose - * Inputs: unsigned long ulStart - holds the SPI start address - * int pnData - pointer to store value read from flash - * long lCount - number of elements to read - */ -ERROR_CODE ReadData(unsigned long ulStart, long lCount, int *pnData) -{ - unsigned long ShiftValue; - char *cnData; - int i; - - /* Pointer cast to be able to increment byte wise */ - - cnData = (char *)pnData; - /* Start SPI interface */ - SetupSPI((COMMON_SPI_SETTINGS | TIMOD01)); - -#ifdef CONFIG_SPI_FLASH_FAST_READ - /* Send the read command to SPI device */ - *pSPI_TDBR = SPI_FAST_READ; -#else - /* Send the read command to SPI device */ - *pSPI_TDBR = SPI_READ; -#endif - SSYNC(); - /* Wait until the instruction has been sent */ - Wait_For_SPIF(); - /* Send the highest byte of the 24 bit address at first */ - ShiftValue = (ulStart >> 16); - /* Send the byte to the SPI device */ - *pSPI_TDBR = ShiftValue; - SSYNC(); - /* Wait until the instruction has been sent */ - Wait_For_SPIF(); - /* Send the middle byte of the 24 bit address at second */ - ShiftValue = (ulStart >> 8); - /* Send the byte to the SPI device */ - *pSPI_TDBR = ShiftValue; - SSYNC(); - /* Wait until the instruction has been sent */ - Wait_For_SPIF(); - /* Send the lowest byte of the 24 bit address finally */ - *pSPI_TDBR = ulStart; - SSYNC(); - /* Wait until the instruction has been sent */ - Wait_For_SPIF(); - -#ifdef CONFIG_SPI_FLASH_FAST_READ - /* Send dummy for FAST_READ */ - *pSPI_TDBR = 0; - SSYNC(); - /* Wait until the instruction has been sent */ - Wait_For_SPIF(); -#endif - - /* After the SPI device address has been placed on the MOSI pin the data can be */ - /* received on the MISO pin. */ - for (i = 0; i < lCount; i++) { - *pSPI_TDBR = 0; - SSYNC(); - while (!(*pSPI_STAT & RXS)) ; - *cnData++ = *pSPI_RDBR; - - if ((i >= SECTOR_SIZE) && (i % SECTOR_SIZE == 0)) - printf("."); - } - - /* Turn off the SPI */ - SPI_OFF(); - - return NO_ERR; -} - -ERROR_CODE WriteFlash(unsigned long ulStartAddr, long lTransferCount, - int *iDataSource, long *lWriteCount) -{ - - unsigned long ulWAddr; - long lWTransferCount = 0; - int i; - char iData; - char *temp = (char *)iDataSource; - ERROR_CODE ErrorCode = NO_ERR; - - /* First, a Write Enable Command must be sent to the SPI. */ - SendSingleCommand(SPI_WREN); - - /* - * Second, the SPI Status Register will be tested whether the - * Write Enable Bit has been set - */ - ErrorCode = Wait_For_WEL(); - if (POLL_TIMEOUT == ErrorCode) { - printf("SPI Write Time Out\n"); - return ErrorCode; - } else - /* Third, the 24 bit address will be shifted out - * the SPI MOSI bytewise. - * Turns the SPI on - */ - SetupSPI((COMMON_SPI_SETTINGS | TIMOD01)); - *pSPI_TDBR = SPI_PP; - SSYNC(); - /*wait until the instruction has been sent */ - Wait_For_SPIF(); - ulWAddr = (ulStartAddr >> 16); - *pSPI_TDBR = ulWAddr; - SSYNC(); - /*wait until the instruction has been sent */ - Wait_For_SPIF(); - ulWAddr = (ulStartAddr >> 8); - *pSPI_TDBR = ulWAddr; - SSYNC(); - /*wait until the instruction has been sent */ - Wait_For_SPIF(); - ulWAddr = ulStartAddr; - *pSPI_TDBR = ulWAddr; - SSYNC(); - /*wait until the instruction has been sent */ - Wait_For_SPIF(); - /* - * Fourth, maximum number of 256 bytes will be taken from the Buffer - * and sent to the SPI device. - */ - for (i = 0; (i < lTransferCount) && (i < 256); i++, lWTransferCount++) { - iData = *temp; - *pSPI_TDBR = iData; - SSYNC(); - /*wait until the instruction has been sent */ - Wait_For_SPIF(); - temp++; - } - - /* Turns the SPI off */ - SPI_OFF(); - - /* - * Sixth, the SPI Write in Progress Bit must be toggled to ensure the - * programming is done before start of next transfer - */ - ErrorCode = Wait_For_Status(WIP); - - if (POLL_TIMEOUT == ErrorCode) { - printf("SPI Program Time out!\n"); - return ErrorCode; - } else - - *lWriteCount = lWTransferCount; - - return ErrorCode; -} - -ERROR_CODE WriteData(unsigned long ulStart, long lCount, int *pnData) -{ - - unsigned long ulWStart = ulStart; - long lWCount = lCount, lWriteCount; - long *pnWriteCount = &lWriteCount; - - ERROR_CODE ErrorCode = NO_ERR; - - while (lWCount != 0) { - ErrorCode = WriteFlash(ulWStart, lWCount, pnData, pnWriteCount); - - /* - * After each function call of WriteFlash the counter - * must be adjusted - */ - lWCount -= *pnWriteCount; - - /* Also, both address pointers must be recalculated. */ - ulWStart += *pnWriteCount; - pnData += *pnWriteCount / 4; - } - - /* return the appropriate error code */ - return ErrorCode; -} - -#endif /* CONFIG_SPI */ |