8xx: Cleanup for partial linking and --gc-sections
[platform/kernel/u-boot.git] / board / flagadm / flash.c
1 /*
2  * (C) Copyright 2001
3  * Wolfgang Denk, DENX Software Engineering, wd@denx.de.
4  *
5  * See file CREDITS for list of people who contributed to this
6  * project.
7  *
8  * This program is free software; you can redistribute it and/or
9  * modify it under the terms of the GNU General Public License as
10  * published by the Free Software Foundation; either version 2 of
11  * the License, or (at your option) any later version.
12  *
13  * This program is distributed in the hope that it will be useful,
14  * but WITHOUT ANY WARRANTY; without even the implied warranty of
15  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16  * GNU General Public License for more details.
17  *
18  * You should have received a copy of the GNU General Public License
19  * along with this program; if not, write to the Free Software
20  * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
21  * MA 02111-1307 USA
22  */
23
24 #include <common.h>
25 #include <mpc8xx.h>
26 #include <flash.h>
27
28 flash_info_t    flash_info[CONFIG_SYS_MAX_FLASH_BANKS]; /* info for FLASH chips */
29
30 /*-----------------------------------------------------------------------
31  * Functions
32  */
33 ulong flash_recognize (vu_long *base);
34 int write_word (flash_info_t *info, ulong dest, ulong data);
35 void flash_get_geometry (vu_long *base, flash_info_t *info);
36 void flash_unprotect(flash_info_t *info);
37 int _flash_real_protect(flash_info_t *info, long idx, int on);
38
39
40 unsigned long flash_init (void)
41 {
42         volatile immap_t        *immap  = (immap_t *)CONFIG_SYS_IMMR;
43         volatile memctl8xx_t    *memctl = &immap->im_memctl;
44         int i;
45         int rec;
46
47         for (i=0; i<CONFIG_SYS_MAX_FLASH_BANKS; ++i) {
48                 flash_info[i].flash_id = FLASH_UNKNOWN;
49         }
50
51         *((vu_short*)CONFIG_SYS_FLASH_BASE) = 0xffff;
52
53         flash_get_geometry ((vu_long*)CONFIG_SYS_FLASH_BASE, &flash_info[0]);
54
55         /* Remap FLASH according to real size */
56         memctl->memc_or0 = CONFIG_SYS_OR_TIMING_FLASH | (-flash_info[0].size & 0xFFFF8000);
57         memctl->memc_br0 = (CONFIG_SYS_FLASH_BASE & BR_BA_MSK) |
58                 (memctl->memc_br0 & ~(BR_BA_MSK));
59
60         rec = flash_recognize((vu_long*)CONFIG_SYS_FLASH_BASE);
61
62         if (rec == FLASH_UNKNOWN) {
63                 printf ("## Unknown FLASH on Bank 0 - Size = 0x%08lx = %ld MB\n",
64                                 flash_info[0].size, flash_info[0].size<<20);
65         }
66
67 #if CONFIG_SYS_FLASH_PROTECTION
68         /*Unprotect all the flash memory*/
69         flash_unprotect(&flash_info[0]);
70 #endif
71
72         *((vu_short*)CONFIG_SYS_FLASH_BASE) = 0xffff;
73
74         return (flash_info[0].size);
75
76 #if CONFIG_SYS_MONITOR_BASE >= CONFIG_SYS_FLASH_BASE
77         /* monitor protection ON by default */
78         flash_protect(FLAG_PROTECT_SET,
79                       CONFIG_SYS_MONITOR_BASE,
80                       CONFIG_SYS_MONITOR_BASE+monitor_flash_len-1,
81                       &flash_info[0]);
82 #endif
83
84 #ifdef  CONFIG_ENV_IS_IN_FLASH
85         /* ENV protection ON by default */
86         flash_protect(FLAG_PROTECT_SET,
87                       CONFIG_ENV_OFFSET,
88                       CONFIG_ENV_OFFSET+CONFIG_ENV_SIZE-1,
89                       &flash_info[0]);
90 #endif
91         return (flash_info[0].size);
92 }
93
94
95 int flash_get_protect_status(flash_info_t * info, long idx)
96 {
97         vu_short * base;
98         ushort res;
99
100 #ifdef DEBUG
101         printf("\n Attempting to set protection info with %d sectors\n", info->sector_count);
102 #endif
103
104
105         base = (vu_short*)info->start[idx];
106
107         *(base) = 0xffff;
108
109         *(base + 0x55) = 0x0098;
110         res = base[0x2];
111
112         *(base) = 0xffff;
113
114         if(res != 0)
115                 res = 1;
116         else
117                 res = 0;
118
119         return res;
120 }
121
122 void flash_get_geometry (vu_long *base, flash_info_t *info)
123 {
124         int i,j;
125         ulong ner = 0;
126         vu_short * sb  = (vu_short*)base;
127         ulong offset = (ulong)base;
128
129         /* Read Device geometry */
130
131         *sb = 0xffff;
132
133         *sb = 0x0090;
134
135         info->flash_id = ((ulong)base[0x0]);
136 #ifdef DEBUG
137         printf("Id is %x\n", (uint)(ulong)info->flash_id);
138 #endif
139
140         *sb = 0xffff;
141
142         *(sb+0x55) = 0x0098;
143
144         info->size = 1 << (sb[0x27]); /* Read flash size */
145
146 #ifdef DEBUG
147         printf("Size is %x\n", (uint)(ulong)info->size);
148 #endif
149
150         *sb = 0xffff;
151
152         *(sb + 0x55) = 0x0098;
153         ner = sb[0x2c] ; /*Number of erase regions*/
154
155 #ifdef DEBUG
156         printf("Number of erase regions %x\n", (uint)ner);
157 #endif
158
159         info->sector_count = 0;
160
161         for(i = 0; i < ner; i++)
162         {
163                 uint s;
164                 uint count;
165                 uint t1,t2,t3,t4;
166
167                 *sb = 0xffff;
168
169                 *(sb + 0x55) = 0x0098;
170
171                 t1 = sb[0x2d + i*4];
172                 t2 = sb[0x2e + i*4];
173                 t3 = sb[0x2f + i*4];
174                 t4 = sb[0x30 + i*4];
175
176                 count = ((t1 & 0x00ff) | (((t2 & 0x00ff) << 8) & 0xff00) )+ 1; /*sector count*/
177                 s = ((t3 & 0x00ff) | (((t4 & 0x00ff) << 8) & 0xff00)) * 256;; /*Sector size*/
178
179 #ifdef DEBUG
180                 printf("count and size %x, %x\n", count, s);
181                 printf("sector count for erase region %d is %d\n", i, count);
182 #endif
183                 for(j = 0; j < count; j++)
184                 {
185 #ifdef DEBUG
186                         printf("%x, ", (uint)offset);
187 #endif
188                         info->start[ info->sector_count + j] = offset;
189                         offset += s;
190                 }
191                 info->sector_count += count;
192         }
193
194         if ((offset - (ulong)base) != info->size)
195                 printf("WARNING reported size %x does not match to calculted size %x.\n"
196                                 , (uint)info->size, (uint)(offset - (ulong)base) );
197
198         /* Next check if there are any sectors protected.*/
199
200         for(i = 0; i < info->sector_count; i++)
201                 info->protect[i] = flash_get_protect_status(info, i);
202
203         *sb = 0xffff;
204 }
205
206 /*-----------------------------------------------------------------------
207  */
208 void flash_print_info  (flash_info_t *info)
209 {
210         int i;
211
212         if (info->flash_id == FLASH_UNKNOWN) {
213                 printf ("missing or unknown FLASH type\n");
214                 return ;
215         }
216
217         switch (info->flash_id & FLASH_VENDMASK) {
218         case INTEL_MANUFACT & FLASH_VENDMASK:
219                 printf ("Intel ");
220                 break;
221         default:
222                 printf ("Unknown Vendor ");
223                 break;
224         }
225
226         switch (info->flash_id & FLASH_TYPEMASK) {
227         case INTEL_ID_28F320C3B & FLASH_TYPEMASK:
228                 printf ("28F320RC3(4 MB)\n");
229                 break;
230         case INTEL_ID_28F320J3A:
231                 printf("28F320J3A (4 MB)\n");
232                 break;
233         default:
234                 printf ("Unknown Chip Type\n");
235                         break;
236         }
237
238         printf ("  Size: %ld MB in %d Sectors\n",
239                 info->size >> 20, info->sector_count);
240
241         printf ("  Sector Start Addresses:");
242         for (i=0; i<info->sector_count; ++i) {
243                 if ((i % 4) == 0)
244                         printf ("\n   ");
245                 printf ("  %02d %08lX%s",
246                         i, info->start[i],
247                         info->protect[i]!=0 ? " (RO)" : "     "
248                 );
249         }
250         printf ("\n");
251         return ;
252 }
253
254 ulong flash_recognize (vu_long *base)
255 {
256         ulong id;
257         ulong res = FLASH_UNKNOWN;
258         vu_short * sb = (vu_short*)base;
259
260         *sb = 0xffff;
261
262         *sb = 0x0090;
263         id = base[0];
264
265         switch (id & 0x00FF0000)
266         {
267                 case (MT_MANUFACT & 0x00FF0000):        /* MT or => Intel */
268                 case (INTEL_ALT_MANU & 0x00FF0000):
269                 res = FLASH_MAN_INTEL;
270                 break;
271         default:
272                 res = FLASH_UNKNOWN;
273         }
274
275         *sb = 0xffff;
276
277         return res;
278 }
279
280 /*-----------------------------------------------------------------------*/
281 #define INTEL_FLASH_STATUS_BLS  0x02
282 #define INTEL_FLASH_STATUS_PSS  0x04
283 #define INTEL_FLASH_STATUS_VPPS 0x08
284 #define INTEL_FLASH_STATUS_PS   0x10
285 #define INTEL_FLASH_STATUS_ES   0x20
286 #define INTEL_FLASH_STATUS_ESS  0x40
287 #define INTEL_FLASH_STATUS_WSMS 0x80
288
289 int     flash_decode_status_bits(char status)
290 {
291         int err = 0;
292
293         if(!(status & INTEL_FLASH_STATUS_WSMS)) {
294                 printf("Busy\n");
295                 err = -1;
296         }
297
298         if(status & INTEL_FLASH_STATUS_ESS) {
299                 printf("Erase suspended\n");
300                 err = -1;
301         }
302
303         if(status & INTEL_FLASH_STATUS_ES) {
304                 printf("Error in block erase\n");
305                 err = -1;
306         }
307
308         if(status & INTEL_FLASH_STATUS_PS) {
309                 printf("Error in programming\n");
310                 err = -1;
311         }
312
313         if(status & INTEL_FLASH_STATUS_VPPS) {
314                 printf("Vpp low, operation aborted\n");
315                 err = -1;
316         }
317
318         if(status & INTEL_FLASH_STATUS_PSS) {
319                 printf("Program is suspended\n");
320                 err = -1;
321         }
322
323         if(status & INTEL_FLASH_STATUS_BLS) {
324                 printf("Attempting to program/erase a locked sector\n");
325                 err = -1;
326         }
327
328         if((status & INTEL_FLASH_STATUS_PS) &&
329            (status & INTEL_FLASH_STATUS_ES) &&
330            (status & INTEL_FLASH_STATUS_ESS)) {
331                 printf("A command sequence error\n");
332                 return -1;
333         }
334
335         return err;
336 }
337
338 /*-----------------------------------------------------------------------
339  */
340
341 int     flash_erase (flash_info_t *info, int s_first, int s_last)
342 {
343         vu_short *addr;
344         int flag, prot, sect;
345         ulong start, now;
346         int rcode = 0;
347
348         if ((s_first < 0) || (s_first > s_last)) {
349                 if (info->flash_id == FLASH_UNKNOWN) {
350                         printf ("- missing\n");
351                 } else {
352                         printf ("- no sectors to erase\n");
353                 }
354                 return 1;
355         }
356
357         if ((info->flash_id & FLASH_VENDMASK) != (INTEL_MANUFACT & FLASH_VENDMASK)) {
358                 printf ("Can't erase unknown flash type %08lx - aborted\n",
359                         info->flash_id);
360                 return 1;
361         }
362
363         prot = 0;
364         for (sect=s_first; sect<=s_last; ++sect) {
365                 if (info->protect[sect]) {
366                         prot++;
367                 }
368         }
369
370         if (prot) {
371                 printf ("- Warning: %d protected sectors will not be erased!\n",
372                         prot);
373         } else {
374                 printf ("\n");
375         }
376
377         start = get_timer (0);
378
379         /* Start erase on unprotected sectors */
380         for (sect = s_first; sect<=s_last; sect++) {
381                 char tmp;
382
383                 if (info->protect[sect] == 0) { /* not protected */
384                         addr = (vu_short *)(info->start[sect]);
385
386                         /* Disable interrupts which might cause a timeout here */
387                         flag = disable_interrupts();
388
389                         /* Single Block Erase Command */
390                         *addr = 0x0020;
391                         /* Confirm */
392                         *addr = 0x00D0;
393                         /* Resume Command, as per errata update */
394                         *addr = 0x00D0;
395
396                         /* re-enable interrupts if necessary */
397                         if (flag)
398                                 enable_interrupts();
399
400                         *addr = 0x70; /*Read status register command*/
401                         tmp = (short)*addr & 0x00FF; /* Read the status */
402                         while (!(tmp & INTEL_FLASH_STATUS_WSMS)) {
403                                 if ((now=get_timer(start)) > CONFIG_SYS_FLASH_ERASE_TOUT) {
404                                         *addr = 0x0050; /* Reset the status register */
405                                         *addr = 0xffff;
406                                         printf ("Timeout\n");
407                                         return 1;
408                                 }
409                                 /* show that we're waiting */
410                                 if ((now - start) > 1000) {     /* every second */
411                                         putc ('.');
412                                 }
413                                 udelay(100000); /* 100 ms */
414                                 *addr = 0x0070; /*Read status register command*/
415                                 tmp = (short)*addr & 0x00FF; /* Read status */
416                                 start = get_timer(0);
417                         }
418                         if( tmp & INTEL_FLASH_STATUS_ES )
419                                 flash_decode_status_bits(tmp);
420
421                         *addr = 0x0050; /* Reset the status register */
422                         *addr = 0xffff; /* Reset to read mode */
423                 }
424         }
425
426
427         printf (" done\n");
428         return rcode;
429 }
430
431 void flash_unprotect (flash_info_t *info)
432 {
433         /*We can only unprotect the whole flash at once*/
434         /*Therefore we must prevent the _flash_real_protect()*/
435         /*from re-protecting sectors, that ware protected before */
436         /*we called flash_real_protect();*/
437
438         int i;
439
440         for(i = 0; i < info->sector_count; i++)
441                 info->protect[i] = 0;
442
443 #ifdef CONFIG_SYS_FLASH_PROTECTION
444                 _flash_real_protect(info, 0, 0);
445 #endif
446 }
447
448 /*-----------------------------------------------------------------------
449  * Copy memory to flash, returns:
450  * 0 - OK
451  * 1 - write timeout
452  * 2 - Flash not erased
453  */
454
455 int write_buff (flash_info_t *info, uchar *src, ulong addr, ulong cnt)
456 {
457         ulong cp, wp, data;
458         int i, l, rc;
459
460         wp = (addr & ~3);       /* get lower word aligned address */
461
462         /*
463          * handle unaligned start bytes
464          */
465         if ((l = addr - wp) != 0) {
466                 data = 0;
467                 for (i=0, cp=wp; i<l; ++i, ++cp) {
468                         data = (data << 8) | (*(uchar *)cp);
469                 }
470                 for (; i<4 && cnt>0; ++i) {
471                         data = (data << 8) | *src++;
472                         --cnt;
473                         ++cp;
474                 }
475                 for (; cnt==0 && i<4; ++i, ++cp) {
476                         data = (data << 8) | (*(uchar *)cp);
477                 }
478
479                 if ((rc = write_word(info, wp, data)) != 0) {
480                         return (rc);
481                 }
482                 wp += 4;
483         }
484
485         /*
486          * handle word aligned part
487          */
488         while (cnt >= 4) {
489                 data = 0;
490                 for (i=0; i<4; ++i) {
491                         data = (data << 8) | *src++;
492                 }
493                 if ((rc = write_word(info, wp, data)) != 0) {
494                         return (rc);
495                 }
496                 wp  += 4;
497                 cnt -= 4;
498         }
499
500         if (cnt == 0) {
501                 return (0);
502         }
503
504         /*
505          * handle unaligned tail bytes
506          */
507         data = 0;
508         for (i=0, cp=wp; i<4 && cnt>0; ++i, ++cp) {
509                 data = (data << 8) | *src++;
510                 --cnt;
511         }
512         for (; i<4; ++i, ++cp) {
513                 data = (data << 8) | (*(uchar *)cp);
514         }
515
516         return (write_word(info, wp, data));
517 }
518
519 /*-----------------------------------------------------------------------
520  * Write a word to Flash, returns:
521  * 0 - OK
522  * 1 - write timeout
523  * 2 - Flash not erased
524  */
525 int write_word (flash_info_t *info, ulong dest, ulong da)
526 {
527         vu_short *addr = (vu_short *)dest;
528         ulong start;
529         char csr;
530         int flag;
531         int i;
532         union {
533                 u32 data32;
534                 u16 data16[2];
535         } data;
536
537         data.data32 = da;
538
539         /* Check if Flash is (sufficiently) erased */
540         if (((*addr & data.data16[0]) != data.data16[0]) ||
541             ((*(addr+1) & data.data16[1]) != data.data16[1])) {
542                 return (2);
543         }
544         /* Disable interrupts which might cause a timeout here */
545         flag = disable_interrupts();
546
547         for(i = 0; i < 2; i++)
548         {
549                 /* Write Command */
550                 *addr = 0x0010;
551
552                 /* Write Data */
553                 *addr = data.data16[i];
554
555                 /* re-enable interrupts if necessary */
556                 if (flag)
557                         enable_interrupts();
558
559                 /* data polling for D7 */
560                 start = get_timer (0);
561                 flag  = 0;
562                 *addr = 0x0070; /*Read statusregister command */
563                 while (((csr = *addr) & INTEL_FLASH_STATUS_WSMS)!=INTEL_FLASH_STATUS_WSMS) {
564                         if (get_timer(start) > CONFIG_SYS_FLASH_WRITE_TOUT) {
565                                 flag = 1;
566                                 break;
567                         }
568                         *addr = 0x0070; /*Read statusregister command */
569                 }
570                 if (csr & INTEL_FLASH_STATUS_PSS) {
571                         printf ("CSR indicates write error (%0x) at %08lx\n",
572                                         csr, (ulong)addr);
573                         flag = 1;
574                 }
575
576                 /* Clear Status Registers Command */
577                 *addr = 0x0050;
578                 /* Reset to read array mode */
579                 *addr = 0xffff;
580                 addr++;
581         }
582
583         return (flag);
584 }
585
586 int flash_real_protect(flash_info_t *info, long offset, int prot)
587 {
588         int i, idx;
589
590         for(idx = 0; idx < info->sector_count; idx++)
591                 if(info->start[idx] == offset)
592                         break;
593
594         if(idx==info->sector_count)
595                 return -1;
596
597         if(prot == 0) {
598                 /* Unprotect one sector, which means unprotect all flash
599                  * and reprotect the other protected sectors.
600                  */
601                 _flash_real_protect(info, 0, 0); /* Unprotects the whole flash*/
602                 info->protect[idx] = 0;
603
604                 for(i = 0; i < info->sector_count; i++)
605                         if(info->protect[i])
606                                 _flash_real_protect(info, i, 1);
607                 }
608         else {
609                 /* We can protect individual sectors */
610                 _flash_real_protect(info, idx, 1);
611         }
612
613         for( i = 0; i < info->sector_count; i++)
614                 info->protect[i] = flash_get_protect_status(info, i);
615
616         return 0;
617 }
618
619 int _flash_real_protect(flash_info_t *info, long idx, int prot)
620 {
621         vu_short *addr;
622         int flag;
623         ushort cmd;
624         ushort tmp;
625         ulong now, start;
626
627         if ((info->flash_id & FLASH_VENDMASK) != (INTEL_MANUFACT & FLASH_VENDMASK)) {
628                 printf ("Can't change protection for unknown flash type %08lx - aborted\n",
629                         info->flash_id);
630                 return -1;
631         }
632
633         if(prot == 0) {
634                 /*Unlock the sector*/
635                 cmd = 0x00D0;
636         }
637         else {
638                 /*Lock the sector*/
639                 cmd = 0x0001;
640         }
641
642         addr = (vu_short *)(info->start[idx]);
643
644         /* If chip is busy, wait for it */
645         start = get_timer(0);
646         *addr = 0x0070; /*Read status register command*/
647         tmp = ((ushort)(*addr))&0x00ff; /*Read the status*/
648         while(!(tmp & INTEL_FLASH_STATUS_WSMS)) {
649                 /*Write State Machine Busy*/
650                 /*Wait untill done or timeout.*/
651                 if ((now=get_timer(start)) > CONFIG_SYS_FLASH_WRITE_TOUT) {
652                         *addr = 0x0050; /* Reset the status register */
653                         *addr = 0xffff; /* Reset the chip */
654                         printf ("TTimeout\n");
655                         return 1;
656                 }
657                 *addr = 0x0070;
658                 tmp = ((ushort)(*addr))&0x00ff; /*Read the status*/
659                 start = get_timer(0);
660         }
661
662         /* Disable interrupts which might cause a timeout here */
663         flag = disable_interrupts();
664
665         /* Unlock block*/
666         *addr = 0x0060;
667
668         *addr = cmd;
669
670         /* re-enable interrupts if necessary */
671         if (flag)
672                 enable_interrupts();
673
674         start = get_timer(0);
675         *addr = 0x0070; /*Read status register command*/
676         tmp = ((ushort)(*addr)) & 0x00FF; /* Read the status */
677         while (!(tmp & INTEL_FLASH_STATUS_WSMS)) {
678                 /* Write State Machine Busy */
679                 if ((now=get_timer(start)) > CONFIG_SYS_FLASH_WRITE_TOUT) {
680                         *addr = 0x0050; /* Reset the status register */
681                         *addr = 0xffff;
682                         printf ("Timeout\n");
683                         return 1;
684                 }
685                 /* show that we're waiting */
686                 if ((now - start) > 1000) {     /* every second */
687                         putc ('.');
688                 }
689                 udelay(100000); /* 100 ms */
690                 *addr = 0x70; /*Read status register command*/
691                 tmp = (short)*addr & 0x00FF; /* Read status */
692                 start = get_timer(0);
693         }
694         if( tmp & INTEL_FLASH_STATUS_PS )
695                 flash_decode_status_bits(tmp);
696
697         *addr =0x0050; /*Clear status register*/
698
699         /* reset to read mode */
700         *addr = 0xffff;
701
702         return 0;
703 }