]> git.kernelconcepts.de Git - karo-tx-uboot.git/blob - board/snmc/qs850/flash.c
rename CFG_ macros to CONFIG_SYS
[karo-tx-uboot.git] / board / snmc / qs850 / flash.c
1 /*
2  * (C) Copyright 2003
3  * MuLogic B.V.
4  *
5  * (C) Copyright 2001
6  * Wolfgang Denk, DENX Software Engineering, wd@denx.de.
7  *
8  * See file CREDITS for list of people who contributed to this
9  * project.
10  *
11  * This program is free software; you can redistribute it and/or
12  * modify it under the terms of the GNU General Public License as
13  * published by the Free Software Foundation; either version 2 of
14  * the License, or (at your option) any later version.
15  *
16  * This program is distributed in the hope that it will be useful,
17  * but WITHOUT ANY WARRANTY; without even the implied warranty of
18  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
19  * GNU General Public License for more details.
20  *
21  * You should have received a copy of the GNU General Public License
22  * along with this program; if not, write to the Free Software
23  * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
24  * MA 02111-1307 USA
25  */
26
27 #include <common.h>
28 #include <ppc4xx.h>
29 #include <asm/u-boot.h>
30 #include <asm/processor.h>
31
32 flash_info_t flash_info[CONFIG_SYS_MAX_FLASH_BANKS]; /* info for FLASH chips */
33
34
35 #define FLASH_WORD_SIZE unsigned long
36 #define FLASH_ID_MASK 0xFFFFFFFF
37
38 /*-----------------------------------------------------------------------
39  * Functions
40  */
41 /* stolen from esteem192e/flash.c */
42 ulong flash_get_size (volatile FLASH_WORD_SIZE *addr, flash_info_t *info);
43
44 static int write_word (flash_info_t *info, ulong dest, ulong data);
45 static void flash_get_offsets (ulong base, flash_info_t *info);
46
47
48 /*-----------------------------------------------------------------------
49  */
50
51 unsigned long flash_init (void)
52 {
53         unsigned long size_b0, size_b1;
54         int i;
55         uint pbcr;
56         unsigned long base_b0, base_b1;
57         volatile FLASH_WORD_SIZE* flash_base;
58
59         /* Init: no FLASHes known */
60         for (i=0; i<CONFIG_SYS_MAX_FLASH_BANKS; ++i) {
61                 flash_info[i].flash_id = FLASH_UNKNOWN;
62         }
63
64         /* Static FLASH Bank configuration here */
65         /* Test for 8M Flash first */
66         debug ("\n## Get flash bank 1 size @ 0x%08x\n",FLASH_BASE0_8M_PRELIM);
67         flash_base = (volatile FLASH_WORD_SIZE*)(FLASH_BASE0_8M_PRELIM);
68         size_b0 = flash_get_size(flash_base, &flash_info[0]);
69
70         if (flash_info[0].flash_id == FLASH_UNKNOWN) {
71                 printf ("## Unknown FLASH on Bank 0 - Size = 0x%08lx = %ld MB\n",
72                 size_b0, size_b0<<20);
73                 return 0;
74         }
75
76         if (size_b0 < 8*1024*1024) {
77                 /* Not quite 8M, try 4M Flash base address */
78                 debug ("\n## Get flash bank 1 size @ 0x%08x\n",FLASH_BASE0_4M_PRELIM);
79                 flash_base = (volatile FLASH_WORD_SIZE*)(FLASH_BASE0_4M_PRELIM);
80                 size_b0 = flash_get_size(flash_base, &flash_info[0]);
81         }
82
83         if (flash_info[0].flash_id == FLASH_UNKNOWN) {
84                 printf ("## Unknown FLASH on Bank 0 - Size = 0x%08lx = %ld MB\n",
85                 size_b0, size_b0<<20);
86                 return 0;
87         }
88
89         /* Only one bank */
90         if (CONFIG_SYS_MAX_FLASH_BANKS == 1) {
91                 /* Setup offsets */
92                 flash_get_offsets ((ulong)flash_base, &flash_info[0]);
93
94                 /* Monitor protection ON by default */
95                 (void)flash_protect(FLAG_PROTECT_SET, CONFIG_SYS_MONITOR_BASE,
96                         CONFIG_SYS_MONITOR_BASE+CONFIG_SYS_MONITOR_LEN-1, &flash_info[0]);
97                 size_b1 = 0 ;
98                 flash_info[0].size = size_b0;
99                 return(size_b0);
100         }
101
102         /* We have 2 banks */
103         size_b1 = flash_get_size(flash_base, &flash_info[1]);
104
105         /* Re-do sizing to get full correct info */
106         if (size_b1) {
107                 mtdcr(ebccfga, pb0cr);
108                 pbcr = mfdcr(ebccfgd);
109                 mtdcr(ebccfga, pb0cr);
110                 base_b1 = -size_b1;
111                 pbcr = (pbcr & 0x0001ffff) | base_b1 | (((size_b1/1024/1024)-1)<<17);
112                 mtdcr(ebccfgd, pbcr);
113         }
114
115         if (size_b0) {
116                 mtdcr(ebccfga, pb1cr);
117                 pbcr = mfdcr(ebccfgd);
118                 mtdcr(ebccfga, pb1cr);
119                 base_b0 = base_b1 - size_b0;
120                 pbcr = (pbcr & 0x0001ffff) | base_b0 | (((size_b0/1024/1024)-1)<<17);
121                 mtdcr(ebccfgd, pbcr);
122         }
123
124         size_b0 = flash_get_size((volatile FLASH_WORD_SIZE *)base_b0, &flash_info[0]);
125         flash_get_offsets (base_b0, &flash_info[0]);
126
127         /* monitor protection ON by default */
128         (void)flash_protect(FLAG_PROTECT_SET, CONFIG_SYS_MONITOR_BASE,
129                 CONFIG_SYS_MONITOR_BASE+CONFIG_SYS_MONITOR_LEN-1, &flash_info[0]);
130
131         if (size_b1) {
132                 /* Re-do sizing to get full correct info */
133                 size_b1 = flash_get_size((volatile FLASH_WORD_SIZE *)base_b1, &flash_info[1]);
134                 flash_get_offsets (base_b1, &flash_info[1]);
135
136                 /* monitor protection ON by default */
137                 (void)flash_protect(FLAG_PROTECT_SET, base_b1+size_b1-CONFIG_SYS_MONITOR_LEN,
138                         base_b1+size_b1-1, &flash_info[1]);
139
140                 /* monitor protection OFF by default (one is enough) */
141                 (void)flash_protect(FLAG_PROTECT_CLEAR, base_b0+size_b0-CONFIG_SYS_MONITOR_LEN,
142                         base_b0+size_b0-1, &flash_info[0]);
143         } else {
144                 flash_info[1].flash_id = FLASH_UNKNOWN;
145                 flash_info[1].sector_count = -1;
146         }
147
148         flash_info[0].size = size_b0;
149         flash_info[1].size = size_b1;
150         return (size_b0 + size_b1);
151 }
152
153
154 /*-----------------------------------------------------------------------
155  This code is specific to the AM29DL163/AM29DL232 for the QS850/QS823.
156  */
157
158 static void flash_get_offsets (ulong base, flash_info_t *info)
159 {
160         int i;
161         long large_sect_size;
162         long small_sect_size;
163
164         /* set up sector start adress table */
165         large_sect_size = info->size / (info->sector_count - 8 + 1);
166         small_sect_size = large_sect_size / 8;
167
168         if (info->flash_id & FLASH_BTYPE) {
169
170                 /* set sector offsets for bottom boot block type */
171                 for (i = 0; i < 7; i++) {
172                         info->start[i] = base;
173                         base += small_sect_size;
174                 }
175
176                 for (; i < info->sector_count; i++) {
177                         info->start[i] = base;
178                         base += large_sect_size;
179                 }
180         }
181         else
182         {
183                 /* set sector offsets for top boot block type */
184                 for (i = 0; i < (info->sector_count - 8); i++) {
185                         info->start[i] = base;
186                         base += large_sect_size;
187                 }
188
189                 for (; i < info->sector_count; i++) {
190                         info->start[i] = base;
191                         base += small_sect_size;
192                 }
193         }
194 }
195
196 /*-----------------------------------------------------------------------
197  */
198
199 void flash_print_info  (flash_info_t *info)
200 {
201         int i;
202         uchar *boottype;
203         uchar botboot[]=", bottom boot sect)\n";
204         uchar topboot[]=", top boot sector)\n";
205
206         if (info->flash_id == FLASH_UNKNOWN) {
207                 printf ("missing or unknown FLASH type\n");
208                 return;
209         }
210
211         switch (info->flash_id & FLASH_VENDMASK) {
212                 case FLASH_MAN_AMD:
213                         printf ("AMD ");
214                         break;
215                 case FLASH_MAN_FUJ:
216                         printf ("FUJITSU ");
217                         break;
218                 case FLASH_MAN_SST:
219                         printf ("SST ");
220                         break;
221                 case FLASH_MAN_STM:
222                         printf ("STM ");
223                         break;
224                 case FLASH_MAN_INTEL:
225                         printf ("INTEL ");
226                         break;
227                 default:
228                         printf ("Unknown Vendor ");
229                         break;
230         }
231
232         if (info->flash_id & 0x0001 ) {
233                 boottype = botboot;
234         } else {
235                 boottype = topboot;
236         }
237
238         switch (info->flash_id & FLASH_TYPEMASK) {
239                 case FLASH_AM160B:
240                         printf ("AM29LV160B (16 Mbit%s",boottype);
241                         break;
242                 case FLASH_AM160T:
243                         printf ("AM29LV160T (16 Mbit%s",boottype);
244                         break;
245                 case FLASH_AMDL163T:
246                         printf ("AM29DL163T (16 Mbit%s",boottype);
247                         break;
248                 case FLASH_AMDL163B:
249                         printf ("AM29DL163B (16 Mbit%s",boottype);
250                         break;
251                 case FLASH_AM320B:
252                         printf ("AM29LV320B (32 Mbit%s",boottype);
253                         break;
254                 case FLASH_AM320T:
255                         printf ("AM29LV320T (32 Mbit%s",boottype);
256                         break;
257                 case FLASH_AMDL323T:
258                         printf ("AM29DL323T (32 Mbit%s",boottype);
259                         break;
260                 case FLASH_AMDL323B:
261                         printf ("AM29DL323B (32 Mbit%s",boottype);
262                         break;
263                 case FLASH_AMDL322T:
264                         printf ("AM29DL322T (32 Mbit%s",boottype);
265                         break;
266                 default:
267                         printf ("Unknown Chip Type\n");
268                         break;
269         }
270
271         printf ("  Size: %ld MB in %d Sectors\n",
272         info->size >> 20, info->sector_count);
273
274         printf ("  Sector Start Addresses:");
275         for (i=0; i<info->sector_count; ++i) {
276                 if ((i % 5) == 0)
277                         printf ("\n   ");
278                 printf (" %08lX%s", info->start[i],
279                         info->protect[i] ? " (RO)" : "     ");
280         }
281         printf ("\n");
282         return;
283 }
284
285
286 /*-----------------------------------------------------------------------
287  * The following code cannot be run from FLASH!
288  */
289 ulong flash_get_size (volatile FLASH_WORD_SIZE *addr, flash_info_t *info)
290 {
291         short i;
292         ulong base = (ulong)addr;
293         FLASH_WORD_SIZE value;
294
295         /* Write auto select command: read Manufacturer ID */
296
297         /*
298          * Note: if it is an AMD flash and the word at addr[0000]
299          * is 0x00890089 this routine will think it is an Intel
300          * flash device and may(most likely) cause trouble.
301          */
302
303         addr[0x0000] = 0x00900090;
304         if(addr[0x0000] != 0x00890089){
305                 addr[0x0555] = 0x00AA00AA;
306                 addr[0x02AA] = 0x00550055;
307                 addr[0x0555] = 0x00900090;
308         }
309         value = addr[0];
310
311         switch (value) {
312                 case (AMD_MANUFACT & FLASH_ID_MASK):
313                         info->flash_id = FLASH_MAN_AMD;
314                         break;
315                 case (FUJ_MANUFACT & FLASH_ID_MASK):
316                         info->flash_id = FLASH_MAN_FUJ;
317                         break;
318                 case (STM_MANUFACT & FLASH_ID_MASK):
319                         info->flash_id = FLASH_MAN_STM;
320                         break;
321                 case (SST_MANUFACT & FLASH_ID_MASK):
322                         info->flash_id = FLASH_MAN_SST;
323                         break;
324                 case (INTEL_MANUFACT & FLASH_ID_MASK):
325                         info->flash_id = FLASH_MAN_INTEL;
326                         break;
327                 default:
328                         info->flash_id = FLASH_UNKNOWN;
329                         info->sector_count = 0;
330                         info->size = 0;
331                         return (0); /* no or unknown flash */
332         }
333
334         value = addr[1]; /* device ID */
335
336         switch (value) {
337                 case (AMD_ID_LV160T & FLASH_ID_MASK):
338                         info->flash_id += FLASH_AM160T;
339                         info->sector_count = 35;
340                         info->size = 0x00400000;
341                         break; /* => 4 MB */
342
343                 case (AMD_ID_LV160B & FLASH_ID_MASK):
344                         info->flash_id += FLASH_AM160B;
345                         info->sector_count = 35;
346                         info->size = 0x00400000;
347                         break; /* => 4 MB */
348
349                 case (AMD_ID_DL163T & FLASH_ID_MASK):
350                         info->flash_id += FLASH_AMDL163T;
351                         info->sector_count = 39;
352                         info->size = 0x00400000;
353                         break; /* => 4 MB */
354
355                 case (AMD_ID_DL163B & FLASH_ID_MASK):
356                         info->flash_id += FLASH_AMDL163B;
357                         info->sector_count = 39;
358                         info->size = 0x00400000;
359                         break; /* => 4 MB */
360
361                 case (AMD_ID_DL323T & FLASH_ID_MASK):
362                         info->flash_id += FLASH_AMDL323T;
363                         info->sector_count = 71;
364                         info->size = 0x00800000;
365                         break; /* => 8 MB */
366
367                 case (AMD_ID_DL323B & FLASH_ID_MASK):
368                         info->flash_id += FLASH_AMDL323B;
369                         info->sector_count = 71;
370                         info->size = 0x00800000;
371                         break; /* => 8 MB */
372
373                 case (AMD_ID_DL322T & FLASH_ID_MASK):
374                         info->flash_id += FLASH_AMDL322T;
375                         info->sector_count = 71;
376                         info->size = 0x00800000;
377                         break; /* => 8 MB */
378
379                 default:
380                         /* FIXME*/
381                         info->flash_id = FLASH_UNKNOWN;
382                         return (0); /* => no or unknown flash */
383         }
384
385         flash_get_offsets(base, info);
386
387         /* check for protected sectors */
388         for (i = 0; i < info->sector_count; i++) {
389                 /* read sector protection at sector address, (A7 .. A0) = 0x02 */
390                 /* D0 = 1 if protected */
391                 addr = (volatile FLASH_WORD_SIZE *)(info->start[i]);
392                 info->protect[i] = addr[2] & 1;
393         }
394
395         /*
396          * Prevent writes to uninitialized FLASH.
397          */
398         if (info->flash_id != FLASH_UNKNOWN) {
399                 addr = (volatile FLASH_WORD_SIZE *)info->start[0];
400                 *addr = (0x00FF00FF & FLASH_ID_MASK);   /* reset bank */
401         }
402
403         return (info->size);
404 }
405
406
407 /*-----------------------------------------------------------------------
408  */
409
410 int flash_erase (flash_info_t *info, int s_first, int s_last)
411 {
412         volatile FLASH_WORD_SIZE *addr=(volatile FLASH_WORD_SIZE*)(info->start[0]);
413         int flag, prot, sect, l_sect;
414         ulong start, now, last;
415         int rcode = 0;
416
417         if ((s_first < 0) || (s_first > s_last)) {
418                 if (info->flash_id == FLASH_UNKNOWN) {
419                         printf ("- missing\n");
420                 } else {
421                         printf ("- no sectors to erase\n");
422                 }
423                 return 1;
424         }
425
426         if ((info->flash_id == FLASH_UNKNOWN) ||
427                 (info->flash_id > FLASH_AMD_COMP) ) {
428                 printf ("Can't erase unknown flash type - aborted\n");
429                 return 1;
430         }
431
432         prot = 0;
433         for (sect=s_first; sect<=s_last; ++sect) {
434                 if (info->protect[sect]) {
435                         prot++;
436                 }
437         }
438
439         if (prot) {
440                 printf ("- Warning: %d protected sectors will not be erased!\n",
441                         prot);
442         } else {
443                 printf ("\n");
444         }
445
446         l_sect = -1;
447
448         /* Disable interrupts which might cause a timeout here */
449         flag = disable_interrupts();
450         addr[0x0555] = 0x00AA00AA;
451         addr[0x02AA] = 0x00550055;
452         addr[0x0555] = 0x00800080;
453         addr[0x0555] = 0x00AA00AA;
454         addr[0x02AA] = 0x00550055;
455         /* Start erase on unprotected sectors */
456         for (sect = s_first; sect<=s_last; sect++) {
457                 if (info->protect[sect] == 0) { /* not protected */
458                         addr = (volatile FLASH_WORD_SIZE *)(info->start[sect]);
459                         addr[0] = (0x00300030 & FLASH_ID_MASK);
460                         l_sect = sect;
461                 }
462         }
463
464         /* re-enable interrupts if necessary */
465         if (flag)
466                 enable_interrupts();
467
468         /* wait at least 80us - let's wait 1 ms */
469         udelay (1000);
470
471         /*
472          * We wait for the last triggered sector
473          */
474         if (l_sect < 0)
475                 goto DONE;
476
477         start = get_timer (0);
478         last  = start;
479         addr = (volatile FLASH_WORD_SIZE*)(info->start[l_sect]);
480         while ((addr[0] & (0x00800080&FLASH_ID_MASK)) !=
481                         (0x00800080&FLASH_ID_MASK)  )
482         {
483                 if ((now = get_timer(start)) > CONFIG_SYS_FLASH_ERASE_TOUT) {
484                         printf ("Timeout\n");
485                         return 1;
486                 }
487                 /* show that we're waiting */
488                 if ((now - last) > 1000) { /* every second */
489                         serial_putc ('.');
490                         last = now;
491                 }
492         }
493
494 DONE:
495         /* reset to read mode */
496         addr = (volatile FLASH_WORD_SIZE *)info->start[0];
497         addr[0] = (0x00F000F0 & FLASH_ID_MASK); /* reset bank */
498
499         printf (" done\n");
500         return rcode;
501 }
502
503 /*-----------------------------------------------------------------------
504  * Copy memory to flash, returns:
505  * 0 - OK
506  * 1 - write timeout
507  * 2 - Flash not erased
508  */
509
510 int write_buff (flash_info_t *info, uchar *src, ulong addr, ulong cnt)
511 {
512         ulong cp, wp, data;
513         int l;
514         int i, rc;
515
516         wp = (addr & ~3); /* get lower word aligned address */
517
518         /*
519          * handle unaligned start bytes
520          */
521         if ((l = addr - wp) != 0) {
522                 data = 0;
523                 for (i=0, cp=wp; i<l; ++i, ++cp) {
524                         data = (data << 8) | (*(uchar *)cp);
525                 }
526                 for (; i<4 && cnt>0; ++i) {
527                         data = (data << 8) | *src++;
528                         --cnt;
529                         ++cp;
530                 }
531                 for (; cnt==0 && i<4; ++i, ++cp) {
532                         data = (data << 8) | (*(uchar *)cp);
533                 }
534
535                 if ((rc = write_word(info, wp, data)) != 0) {
536                         return (rc);
537                 }
538                 wp += 4;
539         }
540
541         /*
542          * handle word aligned part
543          */
544         while (cnt >= 4) {
545                 data = 0;
546                 for (i=0; i<4; ++i) {
547                         data = (data << 8) | *src++;
548                 }
549                 if ((rc = write_word(info, wp, data)) != 0) {
550                         return (rc);
551                 }
552                 wp  += 4;
553                 cnt -= 4;
554         }
555
556         if (cnt == 0) {
557                 return (0);
558         }
559
560         /*
561          * handle unaligned tail bytes
562          */
563         data = 0;
564         for (i=0, cp=wp; i<4 && cnt>0; ++i, ++cp) {
565                 data = (data << 8) | *src++;
566                 --cnt;
567         }
568         for (; i<4; ++i, ++cp) {
569                 data = (data << 8) | (*(uchar *)cp);
570         }
571
572         return (write_word(info, wp, data));
573 }
574
575 /*-----------------------------------------------------------------------
576  * Write a word to Flash, returns:
577  * 0 - OK
578  * 1 - write timeout
579  * 2 - Flash not erased
580  */
581 static int write_word (flash_info_t *info, ulong dest, ulong data)
582 {
583         vu_long *addr = (vu_long*)(info->start[0]);
584         ulong start;
585         int flag;
586
587         /* Check if Flash is (sufficiently) erased */
588         if ((*((vu_long *)dest) & data) != data) {
589                 return (2);
590         }
591
592         /* Disable interrupts which might cause a timeout here */
593         flag = disable_interrupts();
594
595         /* AMD stuff */
596         addr[0x0555] = 0x00AA00AA;
597         addr[0x02AA] = 0x00550055;
598         addr[0x0555] = 0x00A000A0;
599
600         *((vu_long *)dest) = data;
601
602         /* re-enable interrupts if necessary */
603         if (flag)
604                 enable_interrupts();
605
606         /* data polling for D7 */
607         start = get_timer(0);
608
609         while ((*((vu_long *)dest) & 0x00800080) != (data & 0x00800080)) {
610                 if (get_timer(start) > CONFIG_SYS_FLASH_WRITE_TOUT) {
611                         return (1);
612                 }
613         }
614
615         return (0);
616 }