Add qemu 2.4.0
[kvmfornfv.git] / qemu / roms / u-boot / board / eltec / elppc / flash.c
1 /*
2  * (C) Copyright 2000
3  * Wolfgang Denk, DENX Software Engineering, wd@denx.de.
4  *
5  * SPDX-License-Identifier:     GPL-2.0+
6  */
7
8 /*
9  * 07-10-2002 Frank Gottschling: added 29F032 flash (ELPPC).
10  *        fixed monitor protection part
11  *
12  * 09-18-2001 Andreas Heppel: Reduced the code in here to the usage
13  *        of AMD's 29F040 and 29F016 flashes, since the BAB7xx does use
14  *        any other.
15  */
16
17 #include <common.h>
18 #include <asm/processor.h>
19 #include <asm/pci_io.h>
20
21 flash_info_t    flash_info[CONFIG_SYS_MAX_FLASH_BANKS]; /* info for FLASH chips */
22
23 ulong flash_get_size (vu_long *addr, flash_info_t *info);
24 static int write_word (flash_info_t *info, ulong dest, ulong data);
25
26 /*flash command address offsets*/
27
28 #define ADDR0           (0x555)
29 #define ADDR1           (0x2AA)
30 #define ADDR3           (0x001)
31
32 #define FLASH_WORD_SIZE unsigned char
33
34 /*----------------------------------------------------------------------------*/
35
36 unsigned long flash_init (void)
37 {
38     unsigned long size1, size2;
39     int i;
40
41     /* Init: no FLASHes known */
42     for (i=0; i<CONFIG_SYS_MAX_FLASH_BANKS; ++i)
43     {
44         flash_info[i].flash_id = FLASH_UNKNOWN;
45     }
46
47     /* initialise 1st flash */
48     size1 = flash_get_size((vu_long *)FLASH_BASE0_PRELIM, &flash_info[0]);
49
50     if (flash_info[0].flash_id == FLASH_UNKNOWN)
51     {
52         printf ("## Unknown FLASH on Bank 0 - Size = 0x%08lx = %ld MB\n",
53             size1, size1<<20);
54     }
55
56     /* initialise 2nd flash */
57     size2 = flash_get_size((vu_long *)FLASH_BASE1_PRELIM, &flash_info[1]);
58
59     if (flash_info[1].flash_id == FLASH_UNKNOWN)
60     {
61         printf ("## Unknown FLASH on Bank 1 - Size = 0x%08lx = %ld MB\n",
62             size2, size2<<20);
63     }
64
65     /* monitor protection ON by default */
66     if (size1 == 512*1024)
67     {
68         (void)flash_protect(FLAG_PROTECT_SET,
69                 FLASH_BASE0_PRELIM,
70                 FLASH_BASE0_PRELIM+monitor_flash_len-1,
71                 &flash_info[0]);
72     }
73     if (size2 == 512*1024)
74     {
75         (void)flash_protect(FLAG_PROTECT_SET,
76                 FLASH_BASE1_PRELIM,
77                 FLASH_BASE1_PRELIM+monitor_flash_len-1,
78                 &flash_info[1]);
79     }
80     if (size2 == 4*1024*1024)
81     {
82         (void)flash_protect(FLAG_PROTECT_SET,
83                 CONFIG_SYS_FLASH_BASE,
84                 CONFIG_SYS_FLASH_BASE+monitor_flash_len-1,
85                 &flash_info[1]);
86     }
87
88     return (size1 + size2);
89 }
90
91 /*----------------------------------------------------------------------------*/
92
93 void flash_print_info  (flash_info_t *info)
94 {
95     int i;
96     int k;
97     int size;
98     int erased;
99     volatile unsigned long *flash;
100
101     if (info->flash_id == FLASH_UNKNOWN) {
102         printf ("missing or unknown FLASH type\n");
103         flash_init();
104     }
105
106     if (info->flash_id == FLASH_UNKNOWN) {
107         printf ("missing or unknown FLASH type\n");
108         return;
109     }
110
111     switch (info->flash_id & FLASH_VENDMASK) {
112     case FLASH_MAN_AMD:
113         printf ("AMD ");
114         break;
115     default:
116         printf ("Unknown Vendor ");
117         break;
118     }
119
120     switch (info->flash_id & FLASH_TYPEMASK) {
121     case AMD_ID_F040B:
122         printf ("AM29F040B (4 Mbit)\n");
123         break;
124     case AMD_ID_F016D:
125         printf ("AM29F016D (16 Mbit)\n");
126         break;
127     case AMD_ID_F032B:
128         printf ("AM29F032B (32 Mbit)\n");
129         break;
130    default:
131         printf ("Unknown Chip Type\n");
132         break;
133     }
134
135     if (info->size >= (1 << 20)) {
136         printf ("  Size: %ld MB in %d Sectors\n", info->size >> 20, info->sector_count);
137     } else {
138         printf ("  Size: %ld kB in %d Sectors\n", info->size >> 10, info->sector_count);
139     }
140
141     printf ("  Sector Start Addresses:");
142     for (i=0; i<info->sector_count; ++i) {
143         /*
144         * Check if whole sector is erased
145         */
146         if (i != (info->sector_count-1))
147             size = info->start[i+1] - info->start[i];
148         else
149             size = info->start[0] + info->size - info->start[i];
150
151         erased = 1;
152         flash = (volatile unsigned long *)info->start[i];
153         size = size >> 2;        /* divide by 4 for longword access */
154         for (k=0; k<size; k++) {
155             if (*flash++ != 0xffffffff) {
156                 erased = 0;
157                 break;
158             }
159         }
160
161         if ((i % 5) == 0)
162             printf ("\n   ");
163
164         printf (" %08lX%s%s",
165             info->start[i],
166             erased ? " E" : "  ",
167             info->protect[i] ? "RO " : "   ");
168     }
169     printf ("\n");
170 }
171
172 /*----------------------------------------------------------------------------*/
173 /*
174  * The following code cannot be run from FLASH!
175  */
176 ulong flash_get_size (vu_long *addr, flash_info_t *info)
177 {
178     short i;
179     ulong vendor, devid;
180     ulong base = (ulong)addr;
181     volatile unsigned char *caddr = (unsigned char *)addr;
182
183 #ifdef DEBUG
184     printf("flash_get_size for address 0x%lx: \n", (unsigned long)caddr);
185 #endif
186
187     /* Write auto select command: read Manufacturer ID */
188     caddr[0] = 0xF0;   /* reset bank */
189     udelay(10);
190
191     eieio();
192     caddr[0x555] = 0xAA;
193     udelay(10);
194     caddr[0x2AA] = 0x55;
195     udelay(10);
196     caddr[0x555] = 0x90;
197
198     udelay(10);
199
200     vendor = caddr[0];
201     devid = caddr[1];
202
203 #ifdef DEBUG
204     printf("Manufacturer: 0x%lx\n", vendor);
205 #endif
206
207     vendor &= 0xff;
208     devid &= 0xff;
209
210     /* We accept only two AMD types */
211     switch (vendor) {
212     case (FLASH_WORD_SIZE)AMD_MANUFACT:
213         info->flash_id = FLASH_MAN_AMD;
214         break;
215     default:
216         info->flash_id = FLASH_UNKNOWN;
217         info->sector_count = 0;
218         info->size = 0;
219         return (0);         /* no or unknown flash  */
220     }
221
222     switch (devid) {
223     case (FLASH_WORD_SIZE)AMD_ID_F040B:
224         info->flash_id |= AMD_ID_F040B;
225         info->sector_count = 8;
226         info->size = 0x00080000;
227         break;              /* => 0.5 MB      */
228
229     case (FLASH_WORD_SIZE)AMD_ID_F016D:
230         info->flash_id |= AMD_ID_F016D;
231         info->sector_count = 32;
232         info->size         = 0x00200000;
233         break;              /* => 2 MB      */
234
235     case (FLASH_WORD_SIZE)AMD_ID_F032B:
236         info->flash_id |= AMD_ID_F032B;
237         info->sector_count = 64;
238         info->size         = 0x00400000;
239         break;              /* => 4 MB      */
240
241     default:
242         info->flash_id = FLASH_UNKNOWN;
243         return (0);         /* => no or unknown flash */
244
245     }
246
247 #ifdef DEBUG
248     printf("flash id 0x%lx; sector count 0x%x, size 0x%lx\n", info->flash_id, info->sector_count, info->size);
249 #endif
250
251     /* check for protected sectors */
252     for (i = 0; i < info->sector_count; i++) {
253         /* sector base address */
254         info->start[i] = base + i * (info->size / info->sector_count);
255         /* read sector protection at sector address, (A7 .. A0) = 0x02 */
256         /* D0 = 1 if protected */
257         caddr = (volatile unsigned char *)(info->start[i]);
258         info->protect[i] = caddr[2] & 1;
259     }
260
261     /*
262      * Prevent writes to uninitialized FLASH.
263      */
264     if (info->flash_id != FLASH_UNKNOWN) {
265         caddr = (volatile unsigned char *)info->start[0];
266         caddr[0] = 0xF0;   /* reset bank */
267     }
268
269     return (info->size);
270 }
271
272 /*----------------------------------------------------------------------------*/
273
274 int flash_erase (flash_info_t *info, int s_first, int s_last)
275 {
276     volatile FLASH_WORD_SIZE *addr = (FLASH_WORD_SIZE *)(info->start[0]);
277     int flag, prot, sect, l_sect;
278     ulong start, now, last;
279     int rc = 0;
280
281     if ((s_first < 0) || (s_first > s_last)) {
282         if (info->flash_id == FLASH_UNKNOWN) {
283             printf ("- missing\n");
284         } else {
285             printf ("- no sectors to erase\n");
286         }
287         return 1;
288     }
289
290     if ((info->flash_id == FLASH_UNKNOWN) ||
291         (info->flash_id > FLASH_AMD_COMP)) {
292         printf ("Can't erase unknown flash type - aborted\n");
293         return 1;
294     }
295
296     prot = 0;
297     for (sect=s_first; sect<=s_last; ++sect) {
298         if (info->protect[sect]) {
299             prot++;
300         }
301     }
302
303     if (prot) {
304         printf ("- Warning: %d protected sectors will not be erased!\n",
305             prot);
306     } else {
307         printf ("\n");
308     }
309
310     l_sect = -1;
311
312     /* Disable interrupts which might cause a timeout here */
313     flag = disable_interrupts();
314
315     addr[ADDR0] = (FLASH_WORD_SIZE)0x00AA00AA;
316     addr[ADDR1] = (FLASH_WORD_SIZE)0x00550055;
317     addr[ADDR0] = (FLASH_WORD_SIZE)0x00800080;
318     addr[ADDR0] = (FLASH_WORD_SIZE)0x00AA00AA;
319     addr[ADDR1] = (FLASH_WORD_SIZE)0x00550055;
320
321     /* Start erase on unprotected sectors */
322     for (sect = s_first; sect<=s_last; sect++) {
323         if (info->protect[sect] == 0) { /* not protected */
324             addr = (FLASH_WORD_SIZE *)(info->start[sect]);
325             if (info->flash_id & FLASH_MAN_SST) {
326                 addr[ADDR0] = (FLASH_WORD_SIZE)0x00AA00AA;
327                 addr[ADDR1] = (FLASH_WORD_SIZE)0x00550055;
328                 addr[ADDR0] = (FLASH_WORD_SIZE)0x00800080;
329                 addr[ADDR0] = (FLASH_WORD_SIZE)0x00AA00AA;
330                 addr[ADDR1] = (FLASH_WORD_SIZE)0x00550055;
331                 addr[0] = (FLASH_WORD_SIZE)0x00500050;  /* block erase */
332                 udelay(30000);  /* wait 30 ms */
333             }
334             else
335                 addr[0] = (FLASH_WORD_SIZE)0x00300030;  /* sector erase */
336             l_sect = sect;
337         }
338     }
339
340     /* re-enable interrupts if necessary */
341     if (flag)
342         enable_interrupts();
343
344     /* wait at least 80us - let's wait 1 ms */
345     udelay (1000);
346
347     /*
348      * We wait for the last triggered sector
349      */
350     if (l_sect < 0)
351         goto DONE;
352
353     start = get_timer (0);
354     last  = start;
355     addr = (FLASH_WORD_SIZE *)(info->start[l_sect]);
356     while ((addr[0] & (FLASH_WORD_SIZE)0x00800080) != (FLASH_WORD_SIZE)0x00800080) {
357         if ((now = get_timer(start)) > CONFIG_SYS_FLASH_ERASE_TOUT) {
358             printf ("Timeout\n");
359             return 1;
360         }
361         /* show that we're waiting */
362         if ((now - last) > 1000) {  /* every second */
363             serial_putc ('.');
364             last = now;
365         }
366     }
367
368 DONE:
369     /* reset to read mode */
370     addr = (FLASH_WORD_SIZE *)info->start[0];
371     addr[0] = (FLASH_WORD_SIZE)0x00F000F0;  /* reset bank */
372
373     printf (" done\n");
374     return rc;
375 }
376
377 /*----------------------------------------------------------------------------*/
378 /*
379  * Copy memory to flash, returns:
380  * 0 - OK
381  * 1 - write timeout
382  * 2 - Flash not erased
383  */
384 int write_buff (flash_info_t *info, uchar *src, ulong addr, ulong cnt)
385 {
386     ulong cp, wp, data;
387     int i, l, rc;
388
389     wp = (addr & ~3);   /* get lower word aligned address */
390
391     /*
392      * handle unaligned start bytes
393      */
394     if ((l = addr - wp) != 0) {
395         data = 0;
396         for (i=0, cp=wp; i<l; ++i, ++cp) {
397             data = (data << 8) | (*(uchar *)cp);
398         }
399         for (; i<4 && cnt>0; ++i) {
400             data = (data << 8) | *src++;
401             --cnt;
402             ++cp;
403         }
404         for (; cnt==0 && i<4; ++i, ++cp) {
405             data = (data << 8) | (*(uchar *)cp);
406         }
407
408         if ((rc = write_word(info, wp, data)) != 0) {
409             return (rc);
410         }
411         wp += 4;
412     }
413
414     /*
415      * handle word aligned part
416      */
417     while (cnt >= 4) {
418         data = 0;
419         for (i=0; i<4; ++i) {
420             data = (data << 8) | *src++;
421         }
422         if ((rc = write_word(info, wp, data)) != 0) {
423             return (rc);
424         }
425         wp  += 4;
426         cnt -= 4;
427     }
428
429     if (cnt == 0) {
430         return (0);
431     }
432
433     /*
434      * handle unaligned tail bytes
435      */
436     data = 0;
437     for (i=0, cp=wp; i<4 && cnt>0; ++i, ++cp) {
438         data = (data << 8) | *src++;
439         --cnt;
440     }
441     for (; i<4; ++i, ++cp) {
442         data = (data << 8) | (*(uchar *)cp);
443     }
444
445     return (write_word(info, wp, data));
446 }
447
448 /*----------------------------------------------------------------------------*/
449 /* Write a word to Flash, returns:
450  * 0 - OK
451  * 1 - write timeout
452  * 2 - Flash not erased
453  */
454 static int write_word (flash_info_t *info, ulong dest, ulong data)
455 {
456         volatile FLASH_WORD_SIZE *addr2 = (FLASH_WORD_SIZE *)(info->start[0]);
457         volatile FLASH_WORD_SIZE *dest2 = (FLASH_WORD_SIZE *)dest;
458         volatile FLASH_WORD_SIZE *data2 = (FLASH_WORD_SIZE *)&data;
459     ulong start;
460     int flag;
461         int i;
462
463     /* Check if Flash is (sufficiently) erased */
464     if ((*((volatile FLASH_WORD_SIZE *)dest) &
465              (FLASH_WORD_SIZE)data) != (FLASH_WORD_SIZE)data) {
466         return (2);
467     }
468     /* Disable interrupts which might cause a timeout here */
469     flag = disable_interrupts();
470
471         for (i=0; i<4/sizeof(FLASH_WORD_SIZE); i++)
472           {
473             addr2[ADDR0] = (FLASH_WORD_SIZE)0x00AA00AA;
474             addr2[ADDR1] = (FLASH_WORD_SIZE)0x00550055;
475             addr2[ADDR0] = (FLASH_WORD_SIZE)0x00A000A0;
476
477             dest2[i] = data2[i];
478
479             /* re-enable interrupts if necessary */
480             if (flag)
481               enable_interrupts();
482
483             /* data polling for D7 */
484             start = get_timer (0);
485             while ((dest2[i] & (FLASH_WORD_SIZE)0x00800080) !=
486                    (data2[i] & (FLASH_WORD_SIZE)0x00800080)) {
487               if (get_timer(start) > CONFIG_SYS_FLASH_WRITE_TOUT) {
488                 return (1);
489               }
490             }
491           }
492
493     return (0);
494 }
495
496 /*----------------------------------------------------------------------------*/