summaryrefslogtreecommitdiff
path: root/board/bf533-stamp/spi.c
diff options
context:
space:
mode:
authorWolfgang Denk <wd@denx.de>2008-04-08 00:06:47 +0200
committerWolfgang Denk <wd@denx.de>2008-04-08 00:06:47 +0200
commit34e6cb8d1d9dc8194b2d8cad1cc39273ac58f8d8 (patch)
treeb771597b2864542865bfad1e56ecaf4f5641acf9 /board/bf533-stamp/spi.c
parent62479b181460f5bf99517b68059d5ba87908edd3 (diff)
parentd5bffeb868d6b4d462f558dac43011027b6644b7 (diff)
downloadu-boot-imx-34e6cb8d1d9dc8194b2d8cad1cc39273ac58f8d8.zip
u-boot-imx-34e6cb8d1d9dc8194b2d8cad1cc39273ac58f8d8.tar.gz
u-boot-imx-34e6cb8d1d9dc8194b2d8cad1cc39273ac58f8d8.tar.bz2
Merge branch 'master' of git://www.denx.de/git/u-boot-blackfin
Diffstat (limited to 'board/bf533-stamp/spi.c')
-rw-r--r--board/bf533-stamp/spi.c474
1 files changed, 0 insertions, 474 deletions
diff --git a/board/bf533-stamp/spi.c b/board/bf533-stamp/spi.c
deleted file mode 100644
index 15141cf..0000000
--- a/board/bf533-stamp/spi.c
+++ /dev/null
@@ -1,474 +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_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);
-
-/* -------------------
- * Variables
- * ------------------- */
-
-/* **************************************************************************
- *
- * 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 PF2 to be the slave select of the SPI */
- *pSPI_FLG = 0xFB04;
- *pSPI_BAUD = CONFIG_SPI_BAUD;
- *pSPI_CTL = spi_setting;
- 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)) ;
- dummyread = *pSPI_RDBR; /* Read dummy to empty the receive register */
-
-}
-
-ERROR_CODE Wait_For_WEL(void)
-{
- int i;
- char status_register = 0;
- ERROR_CODE ErrorCode = NO_ERR; /* tells us if there was an error erasing flash */
-
- for (i = 0; i < TIMEOUT; i++) {
- status_register = ReadStatusRegister();
- if ((status_register & WEL)) {
- ErrorCode = NO_ERR; /* tells us if there was an error erasing flash */
- 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; /* tells us if there was an error erasing flash */
-
- for (i = 0; i < TIMEOUT; i++) {
- status_register = ReadStatusRegister();
- if (!(status_register & Statusbit)) {
- ErrorCode = NO_ERR; /* tells us if there was an error erasing flash */
- 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;
-
- /* ok */
- 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; /* tells us if there was an error erasing flash */
- 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; /* tells us if there was an error erasing flash */
- 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();
- ShiftValue = (ulSectorOff >> 16); /* Send the highest byte of the 24 bit address at first */
- *pSPI_TDBR = ShiftValue;
- SSYNC();
- Wait_For_SPIF(); /* Wait until the instruction has been sent */
- ShiftValue = (ulSectorOff >> 8); /* Send the middle byte of the 24 bit address at second */
- *pSPI_TDBR = ShiftValue;
- SSYNC();
- Wait_For_SPIF(); /* Wait until the instruction has been sent */
- *pSPI_TDBR = ulSectorOff; /* Send the lowest byte of the 24 bit address finally */
- SSYNC();
- Wait_For_SPIF(); /* Wait until the instruction has been sent */
-
- /*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;
-
- cnData = (char *)pnData; /* Pointer cast to be able to increment byte wise */
-
- /* Start SPI interface */
- SetupSPI((COMMON_SPI_SETTINGS | TIMOD01));
-
- *pSPI_TDBR = SPI_READ; /* Send the read command to SPI device */
- SSYNC();
- Wait_For_SPIF(); /* Wait until the instruction has been sent */
- ShiftValue = (ulStart >> 16); /* Send the highest byte of the 24 bit address at first */
- *pSPI_TDBR = ShiftValue; /* Send the byte to the SPI device */
- SSYNC();
- Wait_For_SPIF(); /* Wait until the instruction has been sent */
- ShiftValue = (ulStart >> 8); /* Send the middle byte of the 24 bit address at second */
- *pSPI_TDBR = ShiftValue; /* Send the byte to the SPI device */
- SSYNC();
- Wait_For_SPIF(); /* Wait until the instruction has been sent */
- *pSPI_TDBR = ulStart; /* Send the lowest byte of the 24 bit address finally */
- SSYNC();
- Wait_For_SPIF(); /* Wait until the instruction has been sent */
-
- /* 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; /*send dummy */
- SSYNC();
- while (!(*pSPI_STAT & RXS)) ;
- *cnData++ = *pSPI_RDBR; /*read */
-
- if ((i >= SECTOR_SIZE) && (i % SECTOR_SIZE == 0))
- printf(".");
- }
-
- SPI_OFF(); /* Turn off the SPI */
-
- 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; /* tells us if there was an error erasing flash */
-
- /* 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. */
- SetupSPI((COMMON_SPI_SETTINGS | TIMOD01)); /* Turns the SPI on */
- *pSPI_TDBR = SPI_PP;
- SSYNC();
- Wait_For_SPIF(); /*wait until the instruction has been sent */
- ulWAddr = (ulStartAddr >> 16);
- *pSPI_TDBR = ulWAddr;
- SSYNC();
- Wait_For_SPIF(); /*wait until the instruction has been sent */
- ulWAddr = (ulStartAddr >> 8);
- *pSPI_TDBR = ulWAddr;
- SSYNC();
- Wait_For_SPIF(); /*wait until the instruction has been sent */
- ulWAddr = ulStartAddr;
- *pSPI_TDBR = ulWAddr;
- SSYNC();
- Wait_For_SPIF(); /*wait until the instruction has been sent */
- /* 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_For_SPIF(); /*wait until the instruction has been sent */
- temp++;
- }
-
- SPI_OFF(); /* Turns the 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 */