blob: 7077e85f4129bc19056b328662f842a2f950ad23 [file] [log] [blame]
Aubrey Li10ebdd92007-03-19 01:24:52 +08001/****************************************************************************
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
34typedef enum {
35 NO_ERR,
36 POLL_TIMEOUT,
37 INVALID_SECTOR,
38 INVALID_BLOCK,
39} ERROR_CODE;
40
41void spi_init_f(void);
42void spi_init_r(void);
43ssize_t spi_read(uchar *, int, uchar *, int);
44ssize_t spi_write(uchar *, int, uchar *, int);
45
46char ReadStatusRegister(void);
47void Wait_For_SPIF(void);
48void SetupSPI(const int spi_setting);
49void SPI_OFF(void);
50void SendSingleCommand(const int iCommand);
51
52ERROR_CODE GetSectorNumber(unsigned long ulOffset, int *pnSector);
53ERROR_CODE EraseBlock(int nBlock);
54ERROR_CODE ReadData(unsigned long ulStart, long lCount, int *pnData);
55ERROR_CODE WriteData(unsigned long ulStart, long lCount, int *pnData);
56ERROR_CODE Wait_For_Status(char Statusbit);
57ERROR_CODE Wait_For_WEL(void);
58
59/*
60 * Function: spi_init_f
61 * Description: Init SPI-Controller (ROM part)
62 * return: ---
63 */
64void 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 */
75void spi_init_r(void)
76{
77 return;
78}
79
80/*
81 * Function: spi_write
82 */
83ssize_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 */
128ssize_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
136void 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
157void 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
173void 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
184void 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
194ERROR_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
212ERROR_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
230char 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
249ERROR_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
265ERROR_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 */
341ERROR_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
409ERROR_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
488ERROR_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 */