]> git.kernelconcepts.de Git - karo-tx-uboot.git/blob - board/prodrive/common/flash.c
nand: remove CONFIG_SYS_NAND_PAGE_SIZE
[karo-tx-uboot.git] / board / prodrive / common / flash.c
1 /*
2  * (C) Copyright 2006
3  * Stefan Roese, DENX Software Engineering, sr@denx.de.
4  *
5  * SPDX-License-Identifier:     GPL-2.0+
6  */
7
8 #include <common.h>
9 #include <asm/processor.h>
10
11 flash_info_t    flash_info[CONFIG_SYS_MAX_FLASH_BANKS]; /* info for FLASH chips */
12
13 /*
14  * Functions
15  */
16 static int write_word(flash_info_t *info, ulong dest, ulong data);
17
18 void flash_print_info(flash_info_t *info)
19 {
20         int i;
21         int k;
22         int size;
23         int erased;
24         volatile unsigned long *flash;
25
26         if (info->flash_id == FLASH_UNKNOWN) {
27                 printf ("missing or unknown FLASH type\n");
28                 return;
29         }
30
31         switch (info->flash_id & FLASH_VENDMASK) {
32         case FLASH_MAN_AMD:     printf ("AMD ");                break;
33         case FLASH_MAN_FUJ:     printf ("FUJITSU ");            break;
34         case FLASH_MAN_SST:     printf ("SST ");                break;
35         case FLASH_MAN_STM:     printf ("ST ");                 break;
36         case FLASH_MAN_EXCEL:   printf ("Excel Semiconductor "); break;
37         default:                printf ("Unknown Vendor ");     break;
38         }
39
40         switch (info->flash_id & FLASH_TYPEMASK) {
41         case FLASH_AM400B:      printf ("AM29LV400B (4 Mbit, bottom boot sect)\n");
42                 break;
43         case FLASH_AM400T:      printf ("AM29LV400T (4 Mbit, top boot sector)\n");
44                 break;
45         case FLASH_AM800B:      printf ("AM29LV800B (8 Mbit, bottom boot sect)\n");
46                 break;
47         case FLASH_AM800T:      printf ("AM29LV800T (8 Mbit, top boot sector)\n");
48                 break;
49         case FLASH_AM160B:      printf ("AM29LV160B (16 Mbit, bottom boot sect)\n");
50                 break;
51         case FLASH_AM160T:      printf ("AM29LV160T (16 Mbit, top boot sector)\n");
52                 break;
53         case FLASH_AM320T:      printf ("AM29LV320T (32 M, top sector)\n");
54                 break;
55         case FLASH_AM320B:      printf ("AM29LV320B (32 M, bottom sector)\n");
56                 break;
57         case FLASH_AMDL322T:    printf ("AM29DL322T (32 M, top sector)\n");
58                 break;
59         case FLASH_AMDL322B:    printf ("AM29DL322B (32 M, bottom sector)\n");
60                 break;
61         case FLASH_AMDL323T:    printf ("AM29DL323T (32 M, top sector)\n");
62                 break;
63         case FLASH_AMDL323B:    printf ("AM29DL323B (32 M, bottom sector)\n");
64                 break;
65         case FLASH_SST020:      printf ("SST39LF/VF020 (2 Mbit, uniform sector size)\n");
66                 break;
67         case FLASH_SST040:      printf ("SST39LF/VF040 (4 Mbit, uniform sector size)\n");
68                 break;
69         default:                printf ("Unknown Chip Type\n");
70                 break;
71         }
72
73         printf ("  Size: %ld MB in %d Sectors\n",
74                 info->size >> 20, info->sector_count);
75
76         printf ("  Sector Start Addresses:");
77         for (i=0; i<info->sector_count; ++i) {
78 #ifdef CONFIG_SYS_FLASH_EMPTY_INFO
79                 /*
80                  * Check if whole sector is erased
81                  */
82                 if (i != (info->sector_count-1))
83                         size = info->start[i+1] - info->start[i];
84                 else
85                         size = info->start[0] + info->size - info->start[i];
86                 erased = 1;
87                 flash = (volatile unsigned long *)info->start[i];
88                 size = size >> 2;        /* divide by 4 for longword access */
89                 for (k=0; k<size; k++) {
90                         if (*flash++ != 0xffffffff) {
91                                 erased = 0;
92                                 break;
93                         }
94                 }
95
96                 if ((i % 5) == 0)
97                         printf ("\n   ");
98                 /* print empty and read-only info */
99                 printf (" %08lX%s%s",
100                         info->start[i],
101                         erased ? " E" : "  ",
102                         info->protect[i] ? "RO " : "   ");
103 #else
104                 if ((i % 5) == 0)
105                         printf ("\n   ");
106                 printf (" %08lX%s",
107                         info->start[i],
108                         info->protect[i] ? " (RO)" : "     ");
109 #endif
110
111         }
112         printf ("\n");
113         return;
114 }
115
116 /*
117  * The following code cannot be run from FLASH!
118  */
119 static ulong flash_get_size(vu_long *addr, flash_info_t *info)
120 {
121         short i;
122         short n;
123         CONFIG_SYS_FLASH_WORD_SIZE value;
124         ulong base = (ulong)addr;
125         volatile CONFIG_SYS_FLASH_WORD_SIZE *addr2 = (CONFIG_SYS_FLASH_WORD_SIZE *)addr;
126
127         /* Write auto select command: read Manufacturer ID */
128         addr2[CONFIG_SYS_FLASH_ADDR0] = (CONFIG_SYS_FLASH_WORD_SIZE)0x00AA00AA;
129         addr2[CONFIG_SYS_FLASH_ADDR1] = (CONFIG_SYS_FLASH_WORD_SIZE)0x00550055;
130         addr2[CONFIG_SYS_FLASH_ADDR0] = (CONFIG_SYS_FLASH_WORD_SIZE)0x00900090;
131
132         value = addr2[CONFIG_SYS_FLASH_READ0];
133
134         switch (value) {
135         case (CONFIG_SYS_FLASH_WORD_SIZE)AMD_MANUFACT:
136                 info->flash_id = FLASH_MAN_AMD;
137                 break;
138         case (CONFIG_SYS_FLASH_WORD_SIZE)FUJ_MANUFACT:
139                 info->flash_id = FLASH_MAN_FUJ;
140                 break;
141         case (CONFIG_SYS_FLASH_WORD_SIZE)SST_MANUFACT:
142                 info->flash_id = FLASH_MAN_SST;
143                 break;
144         case (CONFIG_SYS_FLASH_WORD_SIZE)STM_MANUFACT:
145                 info->flash_id = FLASH_MAN_STM;
146                 break;
147         case (CONFIG_SYS_FLASH_WORD_SIZE)EXCEL_MANUFACT:
148                 info->flash_id = FLASH_MAN_EXCEL;
149                 break;
150         default:
151                 info->flash_id = FLASH_UNKNOWN;
152                 info->sector_count = 0;
153                 info->size = 0;
154                 return (0);                     /* no or unknown flash  */
155         }
156
157         value = addr2[CONFIG_SYS_FLASH_READ1];          /* device ID            */
158
159         switch (value) {
160         case (CONFIG_SYS_FLASH_WORD_SIZE)AMD_ID_LV400T:
161                 info->flash_id += FLASH_AM400T;
162                 info->sector_count = 11;
163                 info->size = 0x00080000;
164                 break;                          /* => 0.5 MB            */
165
166         case (CONFIG_SYS_FLASH_WORD_SIZE)AMD_ID_LV400B:
167                 info->flash_id += FLASH_AM400B;
168                 info->sector_count = 11;
169                 info->size = 0x00080000;
170                 break;                          /* => 0.5 MB            */
171
172         case (CONFIG_SYS_FLASH_WORD_SIZE)AMD_ID_LV800T:
173                 info->flash_id += FLASH_AM800T;
174                 info->sector_count = 19;
175                 info->size = 0x00100000;
176                 break;                          /* => 1 MB              */
177
178         case (CONFIG_SYS_FLASH_WORD_SIZE)AMD_ID_LV800B:
179                 info->flash_id += FLASH_AM800B;
180                 info->sector_count = 19;
181                 info->size = 0x00100000;
182                 break;                          /* => 1 MB              */
183
184         case (CONFIG_SYS_FLASH_WORD_SIZE)AMD_ID_LV160T:
185                 info->flash_id += FLASH_AM160T;
186                 info->sector_count = 35;
187                 info->size = 0x00200000;
188                 break;                          /* => 2 MB              */
189
190         case (CONFIG_SYS_FLASH_WORD_SIZE)AMD_ID_LV160B:
191                 info->flash_id += FLASH_AM160B;
192                 info->sector_count = 35;
193                 info->size = 0x00200000;
194                 break;                          /* => 2 MB              */
195
196         case (CONFIG_SYS_FLASH_WORD_SIZE)AMD_ID_LV320T:
197                 info->flash_id += FLASH_AM320T;
198                 info->sector_count = 71;
199                 info->size = 0x00400000;  break;        /* => 4 MB      */
200
201         case (CONFIG_SYS_FLASH_WORD_SIZE)AMD_ID_LV320B:
202                 info->flash_id += FLASH_AM320B;
203                 info->sector_count = 71;
204                 info->size = 0x00400000;  break;        /* => 4 MB      */
205
206         case (CONFIG_SYS_FLASH_WORD_SIZE)AMD_ID_DL322T:
207                 info->flash_id += FLASH_AMDL322T;
208                 info->sector_count = 71;
209                 info->size = 0x00400000;  break;        /* => 4 MB      */
210
211         case (CONFIG_SYS_FLASH_WORD_SIZE)AMD_ID_DL322B:
212                 info->flash_id += FLASH_AMDL322B;
213                 info->sector_count = 71;
214                 info->size = 0x00400000;  break;        /* => 4 MB      */
215
216         case (CONFIG_SYS_FLASH_WORD_SIZE)AMD_ID_DL323T:
217                 info->flash_id += FLASH_AMDL323T;
218                 info->sector_count = 71;
219                 info->size = 0x00400000;  break;        /* => 4 MB      */
220
221         case (CONFIG_SYS_FLASH_WORD_SIZE)AMD_ID_DL323B:
222                 info->flash_id += FLASH_AMDL323B;
223                 info->sector_count = 71;
224                 info->size = 0x00400000;  break;        /* => 4 MB      */
225
226         case (CONFIG_SYS_FLASH_WORD_SIZE)SST_ID_xF020:
227                 info->flash_id += FLASH_SST020;
228                 info->sector_count = 64;
229                 info->size = 0x00040000;
230                 break;                          /* => 256 kB            */
231
232         case (CONFIG_SYS_FLASH_WORD_SIZE)SST_ID_xF040:
233                 info->flash_id += FLASH_SST040;
234                 info->sector_count = 128;
235                 info->size = 0x00080000;
236                 break;                          /* => 512 kB            */
237
238         default:
239                 info->flash_id = FLASH_UNKNOWN;
240                 return (0);                     /* => no or unknown flash */
241
242         }
243
244         /* set up sector start address table */
245         if ((info->flash_id & FLASH_VENDMASK) == FLASH_MAN_SST) {
246                 for (i = 0; i < info->sector_count; i++)
247                         info->start[i] = base + (i * 0x00001000);
248         } else if (((info->flash_id & FLASH_TYPEMASK) == FLASH_AMDL322B) ||
249                    ((info->flash_id & FLASH_TYPEMASK) == FLASH_AMDL323B) ||
250                    ((info->flash_id & FLASH_TYPEMASK) == FLASH_AM320B) ||
251                    ((info->flash_id & FLASH_TYPEMASK) == FLASH_AMDL324B)) {
252                 /* set sector offsets for bottom boot block type        */
253                 for (i=0; i<8; ++i) {           /*  8 x 8k boot sectors */
254                         info->start[i] = base;
255                         base += 8 << 10;
256                 }
257                 while (i < info->sector_count) {        /* 64k regular sectors  */
258                         info->start[i] = base;
259                         base += 64 << 10;
260                         ++i;
261                 }
262         } else if (((info->flash_id & FLASH_TYPEMASK) == FLASH_AMDL322T) ||
263                    ((info->flash_id & FLASH_TYPEMASK) == FLASH_AMDL323T) ||
264                    ((info->flash_id & FLASH_TYPEMASK) == FLASH_AM320T) ||
265                    ((info->flash_id & FLASH_TYPEMASK) == FLASH_AMDL324T)) {
266                 /* set sector offsets for top boot block type           */
267                 base += info->size;
268                 i = info->sector_count;
269                 for (n=0; n<8; ++n) {           /*  8 x 8k boot sectors */
270                         base -= 8 << 10;
271                         --i;
272                         info->start[i] = base;
273                 }
274                 while (i > 0) {                 /* 64k regular sectors  */
275                         base -= 64 << 10;
276                         --i;
277                         info->start[i] = base;
278                 }
279         } else {
280                 if (info->flash_id & FLASH_BTYPE) {
281                         /* set sector offsets for bottom boot block type        */
282                         info->start[0] = base + 0x00000000;
283                         info->start[1] = base + 0x00004000;
284                         info->start[2] = base + 0x00006000;
285                         info->start[3] = base + 0x00008000;
286                         for (i = 4; i < info->sector_count; i++) {
287                                 info->start[i] = base + (i * 0x00010000) - 0x00030000;
288                         }
289                 } else {
290                         /* set sector offsets for top boot block type           */
291                         i = info->sector_count - 1;
292                         info->start[i--] = base + info->size - 0x00004000;
293                         info->start[i--] = base + info->size - 0x00006000;
294                         info->start[i--] = base + info->size - 0x00008000;
295                         for (; i >= 0; i--) {
296                                 info->start[i] = base + i * 0x00010000;
297                         }
298                 }
299         }
300
301         /* check for protected sectors */
302         for (i = 0; i < info->sector_count; i++) {
303                 /* read sector protection at sector address, (A7 .. A0) = 0x02 */
304                 /* D0 = 1 if protected */
305                 addr2 = (volatile CONFIG_SYS_FLASH_WORD_SIZE *)(info->start[i]);
306                 if ((info->flash_id & FLASH_VENDMASK) != FLASH_MAN_AMD)
307                         info->protect[i] = 0;
308                 else
309                         info->protect[i] = addr2[CONFIG_SYS_FLASH_READ2] & 1;
310         }
311
312         /*
313          * Prevent writes to uninitialized FLASH.
314          */
315         if (info->flash_id != FLASH_UNKNOWN) {
316                 addr2 = (CONFIG_SYS_FLASH_WORD_SIZE *)info->start[0];
317                 *addr2 = (CONFIG_SYS_FLASH_WORD_SIZE)0x00F000F0;        /* reset bank */
318         }
319
320         return (info->size);
321 }
322
323
324 int flash_erase(flash_info_t *info, int s_first, int s_last)
325 {
326         volatile CONFIG_SYS_FLASH_WORD_SIZE *addr = (CONFIG_SYS_FLASH_WORD_SIZE *)(info->start[0]);
327         volatile CONFIG_SYS_FLASH_WORD_SIZE *addr2;
328         int flag, prot, sect, l_sect;
329         ulong start, now, last;
330
331         if ((s_first < 0) || (s_first > s_last)) {
332                 if (info->flash_id == FLASH_UNKNOWN)
333                         printf ("- missing\n");
334                 else
335                         printf ("- no sectors to erase\n");
336                 return 1;
337         }
338
339         if (info->flash_id == FLASH_UNKNOWN) {
340                 printf ("Can't erase unknown flash type - aborted\n");
341                 return 1;
342         }
343
344         prot = 0;
345         for (sect=s_first; sect<=s_last; ++sect)
346                 if (info->protect[sect])
347                         prot++;
348
349         if (prot)
350                 printf ("- Warning: %d protected sectors will not be erased!\n", prot);
351         else
352                 printf ("\n");
353
354         l_sect = -1;
355
356         /* Disable interrupts which might cause a timeout here */
357         flag = disable_interrupts();
358
359         /* Start erase on unprotected sectors */
360         for (sect = s_first; sect<=s_last; sect++) {
361                 if (info->protect[sect] == 0) { /* not protected */
362                         addr2 = (CONFIG_SYS_FLASH_WORD_SIZE *)(info->start[sect]);
363                         if ((info->flash_id & FLASH_VENDMASK) == FLASH_MAN_SST) {
364                                 addr[CONFIG_SYS_FLASH_ADDR0] = (CONFIG_SYS_FLASH_WORD_SIZE)0x00AA00AA;
365                                 addr[CONFIG_SYS_FLASH_ADDR1] = (CONFIG_SYS_FLASH_WORD_SIZE)0x00550055;
366                                 addr[CONFIG_SYS_FLASH_ADDR0] = (CONFIG_SYS_FLASH_WORD_SIZE)0x00800080;
367                                 addr[CONFIG_SYS_FLASH_ADDR0] = (CONFIG_SYS_FLASH_WORD_SIZE)0x00AA00AA;
368                                 addr[CONFIG_SYS_FLASH_ADDR1] = (CONFIG_SYS_FLASH_WORD_SIZE)0x00550055;
369                                 addr2[0] = (CONFIG_SYS_FLASH_WORD_SIZE)0x00300030;  /* sector erase */
370
371                                 /* re-enable interrupts if necessary */
372                                 if (flag) {
373                                         enable_interrupts();
374                                         flag = 0;
375                                 }
376
377                                 /* data polling for D7 */
378                                 start = get_timer (0);
379                                 while ((addr2[0] & (CONFIG_SYS_FLASH_WORD_SIZE)0x00800080) !=
380                                        (CONFIG_SYS_FLASH_WORD_SIZE)0x00800080) {
381                                         if (get_timer(start) > CONFIG_SYS_FLASH_WRITE_TOUT)
382                                                 return (1);
383                                 }
384                         } else {
385                                 if (sect == s_first) {
386                                         addr[CONFIG_SYS_FLASH_ADDR0] = (CONFIG_SYS_FLASH_WORD_SIZE)0x00AA00AA;
387                                         addr[CONFIG_SYS_FLASH_ADDR1] = (CONFIG_SYS_FLASH_WORD_SIZE)0x00550055;
388                                         addr[CONFIG_SYS_FLASH_ADDR0] = (CONFIG_SYS_FLASH_WORD_SIZE)0x00800080;
389                                         addr[CONFIG_SYS_FLASH_ADDR0] = (CONFIG_SYS_FLASH_WORD_SIZE)0x00AA00AA;
390                                         addr[CONFIG_SYS_FLASH_ADDR1] = (CONFIG_SYS_FLASH_WORD_SIZE)0x00550055;
391                                 }
392                                 addr2[0] = (CONFIG_SYS_FLASH_WORD_SIZE)0x00300030;  /* sector erase */
393                         }
394                         l_sect = sect;
395                 }
396         }
397
398         /* re-enable interrupts if necessary */
399         if (flag)
400                 enable_interrupts();
401
402         /* wait at least 80us - let's wait 1 ms */
403         udelay (1000);
404
405         /*
406          * We wait for the last triggered sector
407          */
408         if (l_sect < 0)
409                 goto DONE;
410
411         start = get_timer (0);
412         last  = start;
413         addr = (CONFIG_SYS_FLASH_WORD_SIZE *)(info->start[l_sect]);
414         while ((addr[0] & (CONFIG_SYS_FLASH_WORD_SIZE)0x00800080) != (CONFIG_SYS_FLASH_WORD_SIZE)0x00800080) {
415                 if ((now = get_timer(start)) > CONFIG_SYS_FLASH_ERASE_TOUT) {
416                         printf ("Timeout\n");
417                         return 1;
418                 }
419                 /* show that we're waiting */
420                 if ((now - last) > 1000) {      /* every second */
421                         putc ('.');
422                         last = now;
423                 }
424         }
425
426 DONE:
427         /* reset to read mode */
428         addr = (CONFIG_SYS_FLASH_WORD_SIZE *)info->start[0];
429         addr[0] = (CONFIG_SYS_FLASH_WORD_SIZE)0x00F000F0;       /* reset bank */
430
431         printf (" done\n");
432         return 0;
433 }
434
435 /*
436  * Copy memory to flash, returns:
437  * 0 - OK
438  * 1 - write timeout
439  * 2 - Flash not erased
440  */
441 int write_buff(flash_info_t *info, uchar *src, ulong addr, ulong cnt)
442 {
443         ulong cp, wp, data;
444         int i, l, rc;
445
446         wp = (addr & ~3);       /* get lower word aligned address */
447
448         /*
449          * handle unaligned start bytes
450          */
451         if ((l = addr - wp) != 0) {
452                 data = 0;
453                 for (i=0, cp=wp; i<l; ++i, ++cp) {
454                         data = (data << 8) | (*(uchar *)cp);
455                 }
456                 for (; i<4 && cnt>0; ++i) {
457                         data = (data << 8) | *src++;
458                         --cnt;
459                         ++cp;
460                 }
461                 for (; cnt==0 && i<4; ++i, ++cp) {
462                         data = (data << 8) | (*(uchar *)cp);
463                 }
464
465                 if ((rc = write_word(info, wp, data)) != 0) {
466                         return (rc);
467                 }
468                 wp += 4;
469         }
470
471         /*
472          * handle word aligned part
473          */
474         while (cnt >= 4) {
475                 data = 0;
476                 for (i=0; i<4; ++i)
477                         data = (data << 8) | *src++;
478                 if ((rc = write_word(info, wp, data)) != 0)
479                         return (rc);
480                 wp  += 4;
481                 cnt -= 4;
482         }
483
484         if (cnt == 0)
485                 return (0);
486
487         /*
488          * handle unaligned tail bytes
489          */
490         data = 0;
491         for (i=0, cp=wp; i<4 && cnt>0; ++i, ++cp) {
492                 data = (data << 8) | *src++;
493                 --cnt;
494         }
495         for (; i<4; ++i, ++cp)
496                 data = (data << 8) | (*(uchar *)cp);
497
498         return (write_word(info, wp, data));
499 }
500
501 /*
502  * Write a word to Flash, returns:
503  * 0 - OK
504  * 1 - write timeout
505  * 2 - Flash not erased
506  */
507 static int write_word(flash_info_t *info, ulong dest, ulong data)
508 {
509         volatile CONFIG_SYS_FLASH_WORD_SIZE *addr2 = (CONFIG_SYS_FLASH_WORD_SIZE *)(info->start[0]);
510         volatile CONFIG_SYS_FLASH_WORD_SIZE *dest2 = (CONFIG_SYS_FLASH_WORD_SIZE *)dest;
511         volatile CONFIG_SYS_FLASH_WORD_SIZE *data2 = (CONFIG_SYS_FLASH_WORD_SIZE *)&data;
512         ulong start;
513         int flag;
514         int i;
515
516         /* Check if Flash is (sufficiently) erased */
517         if ((*((vu_long *)dest) & data) != data)
518                 return (2);
519
520         /* Disable interrupts which might cause a timeout here */
521         flag = disable_interrupts();
522
523         for (i=0; i<4/sizeof(CONFIG_SYS_FLASH_WORD_SIZE); i++) {
524                 addr2[CONFIG_SYS_FLASH_ADDR0] = (CONFIG_SYS_FLASH_WORD_SIZE)0x00AA00AA;
525                 addr2[CONFIG_SYS_FLASH_ADDR1] = (CONFIG_SYS_FLASH_WORD_SIZE)0x00550055;
526                 addr2[CONFIG_SYS_FLASH_ADDR0] = (CONFIG_SYS_FLASH_WORD_SIZE)0x00A000A0;
527
528                 dest2[i] = data2[i];
529
530                 /* re-enable interrupts if necessary */
531                 if (flag)
532                         enable_interrupts();
533
534                 /* data polling for D7 */
535                 start = get_timer (0);
536                 while ((dest2[i] & (CONFIG_SYS_FLASH_WORD_SIZE)0x00800080) !=
537                        (data2[i] & (CONFIG_SYS_FLASH_WORD_SIZE)0x00800080)) {
538                         if (get_timer(start) > CONFIG_SYS_FLASH_WRITE_TOUT)
539                                 return (1);
540                 }
541         }
542
543         return (0);
544 }