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