spi.c 13 KB

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