spi.c 13 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473
  1. /****************************************************************************
  2. * SPI flash driver for M25P64
  3. ****************************************************************************/
  4. #include <common.h>
  5. #include <linux/ctype.h>
  6. #include <asm/io.h>
  7. #if defined(CONFIG_SPI)
  8. /*Application definitions */
  9. #define NUM_SECTORS 128 /* number of sectors */
  10. #define SECTOR_SIZE 0x10000
  11. #define NOP_NUM 1000
  12. #define COMMON_SPI_SETTINGS (SPE|MSTR|CPHA|CPOL) /*Settings to the SPI_CTL */
  13. #define TIMOD01 (0x01) /*stes the SPI to work with core instructions */
  14. /*Flash commands */
  15. #define SPI_WREN (0x06) /*Set Write Enable Latch */
  16. #define SPI_WRDI (0x04) /*Reset Write Enable Latch */
  17. #define SPI_RDSR (0x05) /*Read Status Register */
  18. #define SPI_WRSR (0x01) /*Write Status Register */
  19. #define SPI_READ (0x03) /*Read data from memory */
  20. #define SPI_PP (0x02) /*Program Data into memory */
  21. #define SPI_SE (0xD8) /*Erase one sector in memory */
  22. #define SPI_BE (0xC7) /*Erase all memory */
  23. #define WIP (0x1) /*Check the write in progress bit of the SPI status register */
  24. #define WEL (0x2) /*Check the write enable bit of the SPI status register */
  25. #define TIMEOUT 350000000
  26. typedef enum {
  27. NO_ERR,
  28. POLL_TIMEOUT,
  29. INVALID_SECTOR,
  30. INVALID_BLOCK,
  31. } ERROR_CODE;
  32. void spi_init_f(void);
  33. void spi_init_r(void);
  34. ssize_t spi_read(uchar *, int, uchar *, int);
  35. ssize_t spi_write(uchar *, int, uchar *, int);
  36. char ReadStatusRegister(void);
  37. void Wait_For_SPIF(void);
  38. void SetupSPI(const int spi_setting);
  39. void SPI_OFF(void);
  40. void SendSingleCommand(const int iCommand);
  41. ERROR_CODE GetSectorNumber(unsigned long ulOffset, int *pnSector);
  42. ERROR_CODE EraseBlock(int nBlock);
  43. ERROR_CODE ReadData(unsigned long ulStart, long lCount, int *pnData);
  44. ERROR_CODE WriteData(unsigned long ulStart, long lCount, int *pnData);
  45. ERROR_CODE Wait_For_Status(char Statusbit);
  46. ERROR_CODE Wait_For_WEL(void);
  47. /* -------------------
  48. * Variables
  49. * ------------------- */
  50. /* **************************************************************************
  51. *
  52. * Function: spi_init_f
  53. *
  54. * Description: Init SPI-Controller (ROM part)
  55. *
  56. * return: ---
  57. *
  58. * *********************************************************************** */
  59. void spi_init_f(void)
  60. {
  61. }
  62. /* **************************************************************************
  63. *
  64. * Function: spi_init_r
  65. *
  66. * Description: Init SPI-Controller (RAM part) -
  67. * The malloc engine is ready and we can move our buffers to
  68. * normal RAM
  69. *
  70. * return: ---
  71. *
  72. * *********************************************************************** */
  73. void spi_init_r(void)
  74. {
  75. return;
  76. }
  77. /****************************************************************************
  78. * Function: spi_write
  79. **************************************************************************** */
  80. ssize_t spi_write(uchar * addr, int alen, uchar * buffer, int len)
  81. {
  82. unsigned long offset;
  83. int start_block, end_block;
  84. int start_byte, end_byte;
  85. ERROR_CODE result = NO_ERR;
  86. uchar temp[SECTOR_SIZE];
  87. int i, num;
  88. offset = addr[0] << 16 | addr[1] << 8 | addr[2];
  89. /* Get the start block number */
  90. result = GetSectorNumber(offset, &start_block);
  91. if (result == INVALID_SECTOR) {
  92. printf("Invalid sector! ");
  93. return 0;
  94. }
  95. /* Get the end block number */
  96. result = GetSectorNumber(offset + len - 1, &end_block);
  97. if (result == INVALID_SECTOR) {
  98. printf("Invalid sector! ");
  99. return 0;
  100. }
  101. for (num = start_block; num <= end_block; num++) {
  102. ReadData(num * SECTOR_SIZE, SECTOR_SIZE, (int *)temp);
  103. start_byte = num * SECTOR_SIZE;
  104. end_byte = (num + 1) * SECTOR_SIZE - 1;
  105. if (start_byte < offset)
  106. start_byte = offset;
  107. if (end_byte > (offset + len))
  108. end_byte = (offset + len - 1);
  109. for (i = start_byte; i <= end_byte; i++)
  110. temp[i - num * SECTOR_SIZE] = buffer[i - offset];
  111. EraseBlock(num);
  112. result = WriteData(num * SECTOR_SIZE, SECTOR_SIZE, (int *)temp);
  113. if (result != NO_ERR)
  114. return 0;
  115. printf(".");
  116. }
  117. return len;
  118. }
  119. /****************************************************************************
  120. * Function: spi_read
  121. **************************************************************************** */
  122. ssize_t spi_read(uchar * addr, int alen, uchar * buffer, int len)
  123. {
  124. unsigned long offset;
  125. offset = addr[0] << 16 | addr[1] << 8 | addr[2];
  126. ReadData(offset, len, (int *)buffer);
  127. return len;
  128. }
  129. void SendSingleCommand(const int iCommand)
  130. {
  131. unsigned short dummy;
  132. /*turns on the SPI in single write mode */
  133. SetupSPI((COMMON_SPI_SETTINGS | TIMOD01));
  134. /*sends the actual command to the SPI TX register */
  135. *pSPI_TDBR = iCommand;
  136. sync();
  137. /*The SPI status register will be polled to check the SPIF bit */
  138. Wait_For_SPIF();
  139. dummy = *pSPI_RDBR;
  140. /*The SPI will be turned off */
  141. SPI_OFF();
  142. }
  143. void SetupSPI(const int spi_setting)
  144. {
  145. if (icache_status() || dcache_status())
  146. udelay(CONFIG_CCLK_HZ / 50000000);
  147. /*sets up the PF2 to be the slave select of the SPI */
  148. *pSPI_FLG = 0xFB04;
  149. *pSPI_BAUD = CONFIG_SPI_BAUD;
  150. *pSPI_CTL = spi_setting;
  151. sync();
  152. }
  153. void SPI_OFF(void)
  154. {
  155. *pSPI_CTL = 0x0400; /* disable SPI */
  156. *pSPI_FLG = 0;
  157. *pSPI_BAUD = 0;
  158. sync();
  159. udelay(CONFIG_CCLK_HZ / 50000000);
  160. }
  161. void Wait_For_SPIF(void)
  162. {
  163. unsigned short dummyread;
  164. while ((*pSPI_STAT & TXS)) ;
  165. while (!(*pSPI_STAT & SPIF)) ;
  166. while (!(*pSPI_STAT & RXS)) ;
  167. dummyread = *pSPI_RDBR; /* Read dummy to empty the receive register */
  168. }
  169. ERROR_CODE Wait_For_WEL(void)
  170. {
  171. int i;
  172. char status_register = 0;
  173. ERROR_CODE ErrorCode = NO_ERR; /* tells us if there was an error erasing flash */
  174. for (i = 0; i < TIMEOUT; i++) {
  175. status_register = ReadStatusRegister();
  176. if ((status_register & WEL)) {
  177. ErrorCode = NO_ERR; /* tells us if there was an error erasing flash */
  178. break;
  179. }
  180. ErrorCode = POLL_TIMEOUT; /* Time out error */
  181. };
  182. return ErrorCode;
  183. }
  184. ERROR_CODE Wait_For_Status(char Statusbit)
  185. {
  186. int i;
  187. char status_register = 0xFF;
  188. ERROR_CODE ErrorCode = NO_ERR; /* tells us if there was an error erasing flash */
  189. for (i = 0; i < TIMEOUT; i++) {
  190. status_register = ReadStatusRegister();
  191. if (!(status_register & Statusbit)) {
  192. ErrorCode = NO_ERR; /* tells us if there was an error erasing flash */
  193. break;
  194. }
  195. ErrorCode = POLL_TIMEOUT; /* Time out error */
  196. };
  197. return ErrorCode;
  198. }
  199. char ReadStatusRegister(void)
  200. {
  201. char status_register = 0;
  202. SetupSPI((COMMON_SPI_SETTINGS | TIMOD01)); /* Turn on the SPI */
  203. *pSPI_TDBR = SPI_RDSR; /* send instruction to read status register */
  204. sync();
  205. Wait_For_SPIF(); /*wait until the instruction has been sent */
  206. *pSPI_TDBR = 0; /*send dummy to receive the status register */
  207. sync();
  208. Wait_For_SPIF(); /*wait until the data has been sent */
  209. status_register = *pSPI_RDBR; /*read the status register */
  210. SPI_OFF(); /* Turn off the SPI */
  211. return status_register;
  212. }
  213. ERROR_CODE GetSectorNumber(unsigned long ulOffset, int *pnSector)
  214. {
  215. int nSector = 0;
  216. ERROR_CODE ErrorCode = NO_ERR;
  217. if (ulOffset > (NUM_SECTORS * 0x10000 - 1)) {
  218. ErrorCode = INVALID_SECTOR;
  219. return ErrorCode;
  220. }
  221. nSector = (int)ulOffset / 0x10000;
  222. *pnSector = nSector;
  223. /* ok */
  224. return ErrorCode;
  225. }
  226. ERROR_CODE EraseBlock(int nBlock)
  227. {
  228. unsigned long ulSectorOff = 0x0, ShiftValue;
  229. ERROR_CODE ErrorCode = NO_ERR;
  230. /* if the block is invalid just return */
  231. if ((nBlock < 0) || (nBlock > NUM_SECTORS)) {
  232. ErrorCode = INVALID_BLOCK; /* tells us if there was an error erasing flash */
  233. return ErrorCode;
  234. }
  235. /* figure out the offset of the block in flash */
  236. if ((nBlock >= 0) && (nBlock < NUM_SECTORS)) {
  237. ulSectorOff = (nBlock * SECTOR_SIZE);
  238. } else {
  239. ErrorCode = INVALID_BLOCK; /* tells us if there was an error erasing flash */
  240. return ErrorCode;
  241. }
  242. /* A write enable instruction must previously have been executed */
  243. SendSingleCommand(SPI_WREN);
  244. /*The status register will be polled to check the write enable latch "WREN" */
  245. ErrorCode = Wait_For_WEL();
  246. if (POLL_TIMEOUT == ErrorCode) {
  247. printf("SPI Erase block error\n");
  248. return ErrorCode;
  249. } else
  250. /*Turn on the SPI to send single commands */
  251. SetupSPI((COMMON_SPI_SETTINGS | TIMOD01));
  252. /* Send the erase block command to the flash followed by the 24 address */
  253. /* to point to the start of a sector. */
  254. *pSPI_TDBR = SPI_SE;
  255. sync();
  256. Wait_For_SPIF();
  257. ShiftValue = (ulSectorOff >> 16); /* Send the highest byte of the 24 bit address at first */
  258. *pSPI_TDBR = ShiftValue;
  259. sync();
  260. Wait_For_SPIF(); /* Wait until the instruction has been sent */
  261. ShiftValue = (ulSectorOff >> 8); /* Send the middle byte of the 24 bit address at second */
  262. *pSPI_TDBR = ShiftValue;
  263. sync();
  264. Wait_For_SPIF(); /* Wait until the instruction has been sent */
  265. *pSPI_TDBR = ulSectorOff; /* Send the lowest byte of the 24 bit address finally */
  266. sync();
  267. Wait_For_SPIF(); /* Wait until the instruction has been sent */
  268. /*Turns off the SPI */
  269. SPI_OFF();
  270. /* Poll the status register to check the Write in Progress bit */
  271. /* Sector erase takes time */
  272. ErrorCode = Wait_For_Status(WIP);
  273. /* block erase should be complete */
  274. return ErrorCode;
  275. }
  276. /*****************************************************************************
  277. * ERROR_CODE ReadData()
  278. *
  279. * Read a value from flash for verify purpose
  280. *
  281. * Inputs: unsigned long ulStart - holds the SPI start address
  282. * int pnData - pointer to store value read from flash
  283. * long lCount - number of elements to read
  284. ***************************************************************************** */
  285. ERROR_CODE ReadData(unsigned long ulStart, long lCount, int *pnData)
  286. {
  287. unsigned long ShiftValue;
  288. char *cnData;
  289. int i;
  290. cnData = (char *)pnData; /* Pointer cast to be able to increment byte wise */
  291. /* Start SPI interface */
  292. SetupSPI((COMMON_SPI_SETTINGS | TIMOD01));
  293. *pSPI_TDBR = SPI_READ; /* Send the read command to SPI device */
  294. sync();
  295. Wait_For_SPIF(); /* Wait until the instruction has been sent */
  296. ShiftValue = (ulStart >> 16); /* Send the highest byte of the 24 bit address at first */
  297. *pSPI_TDBR = ShiftValue; /* Send the byte to the SPI device */
  298. sync();
  299. Wait_For_SPIF(); /* Wait until the instruction has been sent */
  300. ShiftValue = (ulStart >> 8); /* Send the middle byte of the 24 bit address at second */
  301. *pSPI_TDBR = ShiftValue; /* Send the byte to the SPI device */
  302. sync();
  303. Wait_For_SPIF(); /* Wait until the instruction has been sent */
  304. *pSPI_TDBR = ulStart; /* Send the lowest byte of the 24 bit address finally */
  305. sync();
  306. Wait_For_SPIF(); /* Wait until the instruction has been sent */
  307. /* After the SPI device address has been placed on the MOSI pin the data can be */
  308. /* received on the MISO pin. */
  309. for (i = 0; i < lCount; i++) {
  310. *pSPI_TDBR = 0; /*send dummy */
  311. sync();
  312. while (!(*pSPI_STAT & RXS)) ;
  313. *cnData++ = *pSPI_RDBR; /*read */
  314. if ((i >= SECTOR_SIZE) && (i % SECTOR_SIZE == 0))
  315. printf(".");
  316. }
  317. SPI_OFF(); /* Turn off the SPI */
  318. return NO_ERR;
  319. }
  320. ERROR_CODE WriteFlash(unsigned long ulStartAddr, long lTransferCount,
  321. int *iDataSource, long *lWriteCount)
  322. {
  323. unsigned long ulWAddr;
  324. long lWTransferCount = 0;
  325. int i;
  326. char iData;
  327. char *temp = (char *)iDataSource;
  328. ERROR_CODE ErrorCode = NO_ERR; /* tells us if there was an error erasing flash */
  329. /* First, a Write Enable Command must be sent to the SPI. */
  330. SendSingleCommand(SPI_WREN);
  331. /* Second, the SPI Status Register will be tested whether the */
  332. /* Write Enable Bit has been set. */
  333. ErrorCode = Wait_For_WEL();
  334. if (POLL_TIMEOUT == ErrorCode) {
  335. printf("SPI Write Time Out\n");
  336. return ErrorCode;
  337. } else
  338. /* Third, the 24 bit address will be shifted out the SPI MOSI bytewise. */
  339. SetupSPI((COMMON_SPI_SETTINGS | TIMOD01)); /* Turns the SPI on */
  340. *pSPI_TDBR = SPI_PP;
  341. sync();
  342. Wait_For_SPIF(); /*wait until the instruction has been sent */
  343. ulWAddr = (ulStartAddr >> 16);
  344. *pSPI_TDBR = ulWAddr;
  345. sync();
  346. Wait_For_SPIF(); /*wait until the instruction has been sent */
  347. ulWAddr = (ulStartAddr >> 8);
  348. *pSPI_TDBR = ulWAddr;
  349. sync();
  350. Wait_For_SPIF(); /*wait until the instruction has been sent */
  351. ulWAddr = ulStartAddr;
  352. *pSPI_TDBR = ulWAddr;
  353. sync();
  354. Wait_For_SPIF(); /*wait until the instruction has been sent */
  355. /* Fourth, maximum number of 256 bytes will be taken from the Buffer */
  356. /* and sent to the SPI device. */
  357. for (i = 0; (i < lTransferCount) && (i < 256); i++, lWTransferCount++) {
  358. iData = *temp;
  359. *pSPI_TDBR = iData;
  360. sync();
  361. Wait_For_SPIF(); /*wait until the instruction has been sent */
  362. temp++;
  363. }
  364. SPI_OFF(); /* Turns the SPI off */
  365. /* Sixth, the SPI Write in Progress Bit must be toggled to ensure the */
  366. /* programming is done before start of next transfer. */
  367. ErrorCode = Wait_For_Status(WIP);
  368. if (POLL_TIMEOUT == ErrorCode) {
  369. printf("SPI Program Time out!\n");
  370. return ErrorCode;
  371. } else
  372. *lWriteCount = lWTransferCount;
  373. return ErrorCode;
  374. }
  375. ERROR_CODE WriteData(unsigned long ulStart, long lCount, int *pnData)
  376. {
  377. unsigned long ulWStart = ulStart;
  378. long lWCount = lCount, lWriteCount;
  379. long *pnWriteCount = &lWriteCount;
  380. ERROR_CODE ErrorCode = NO_ERR;
  381. while (lWCount != 0) {
  382. ErrorCode = WriteFlash(ulWStart, lWCount, pnData, pnWriteCount);
  383. /* After each function call of WriteFlash the counter must be adjusted */
  384. lWCount -= *pnWriteCount;
  385. /* Also, both address pointers must be recalculated. */
  386. ulWStart += *pnWriteCount;
  387. pnData += *pnWriteCount / 4;
  388. }
  389. /* return the appropriate error code */
  390. return ErrorCode;
  391. }
  392. #endif /* CONFIG_SPI */