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