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