Add qemu 2.4.0
[kvmfornfv.git] / qemu / roms / u-boot / board / stx / stxgp3 / flash.c
1 /*
2  * (C) Copyright 2003, Dan Malek, Embedded Edge, LLC.  <dan@embeddededge.com>
3  * Copied from ADS85xx.
4  * Updated to support the Silicon Tx GP3 8560.  We should only find
5  * two Intel 28F640 parts in 16-bit mode (i.e. 32-bit wide flash),
6  * but I left other code here in case people order custom boards.
7  *
8  * (C) Copyright 2003 Motorola Inc.
9  *  Xianghua Xiao,(X.Xiao@motorola.com)
10  *
11  * (C) Copyright 2000, 2001
12  *  Wolfgang Denk, DENX Software Engineering, wd@denx.de.
13  *
14  * (C) Copyright 2001, Stuart Hughes, Lineo Inc, stuarth@lineo.com
15  * Add support the Sharp chips on the mpc8260ads.
16  * I started with board/ip860/flash.c and made changes I found in
17  * the MTD project by David Schleef.
18  *
19  * SPDX-License-Identifier:     GPL-2.0+
20  */
21
22 #include <common.h>
23
24 #if !defined(CONFIG_SYS_NO_FLASH)
25
26 flash_info_t    flash_info[CONFIG_SYS_MAX_FLASH_BANKS]; /* info for FLASH chips */
27
28 #if defined(CONFIG_ENV_IS_IN_FLASH)
29 # ifndef  CONFIG_ENV_ADDR
30 #  define CONFIG_ENV_ADDR       (CONFIG_SYS_FLASH_BASE + CONFIG_ENV_OFFSET)
31 # endif
32 # ifndef  CONFIG_ENV_SIZE
33 #  define CONFIG_ENV_SIZE       CONFIG_ENV_SECT_SIZE
34 # endif
35 # ifndef  CONFIG_ENV_SECT_SIZE
36 #  define CONFIG_ENV_SECT_SIZE  CONFIG_ENV_SIZE
37 # endif
38 #endif
39
40 #undef DEBUG
41
42 /*-----------------------------------------------------------------------
43  * Functions
44  */
45 static ulong flash_get_size (vu_long *addr, flash_info_t *info);
46 static int write_word (flash_info_t *info, ulong dest, ulong data);
47 static int clear_block_lock_bit(vu_long * addr);
48 /*-----------------------------------------------------------------------
49  */
50
51 unsigned long flash_init (void)
52 {
53         unsigned long size;
54         int i;
55
56         /* Init: enable write,
57          * or we cannot even write flash commands
58          */
59         for (i=0; i<CONFIG_SYS_MAX_FLASH_BANKS; ++i) {
60                 flash_info[i].flash_id = FLASH_UNKNOWN;
61
62                 /* set the default sector offset */
63         }
64
65         /* Static FLASH Bank configuration here - FIXME XXX */
66
67         size = flash_get_size((vu_long *)CONFIG_SYS_FLASH_BASE, &flash_info[0]);
68
69         if (flash_info[0].flash_id == FLASH_UNKNOWN) {
70                 printf ("## Unknown FLASH on Bank 0 - Size = 0x%08lx = %ld MB\n",
71                         size, size<<20);
72         }
73
74         /* Re-do sizing to get full correct info */
75         size = flash_get_size((vu_long *)CONFIG_SYS_FLASH_BASE, &flash_info[0]);
76
77         flash_info[0].size = size;
78
79 #if CONFIG_SYS_MONITOR_BASE >= CONFIG_SYS_FLASH_BASE
80         /* monitor protection ON by default */
81         flash_protect(FLAG_PROTECT_SET,
82                       CONFIG_SYS_MONITOR_BASE,
83                       CONFIG_SYS_MONITOR_BASE+monitor_flash_len-1,
84                       &flash_info[0]);
85
86 #ifdef  CONFIG_ENV_IS_IN_FLASH
87         /* ENV protection ON by default */
88         flash_protect(FLAG_PROTECT_SET,
89                       CONFIG_ENV_ADDR,
90                       CONFIG_ENV_ADDR+CONFIG_ENV_SECT_SIZE-1,
91                       &flash_info[0]);
92 #endif
93 #endif
94         return (size);
95 }
96
97 /*-----------------------------------------------------------------------
98  */
99 void flash_print_info  (flash_info_t *info)
100 {
101         int i;
102
103         if (info->flash_id == FLASH_UNKNOWN) {
104                 printf ("missing or unknown FLASH type\n");
105                 return;
106         }
107
108         switch (info->flash_id & FLASH_VENDMASK) {
109         case FLASH_MAN_INTEL:   printf ("Intel ");              break;
110         case FLASH_MAN_SHARP:   printf ("Sharp ");              break;
111         default:                printf ("Unknown Vendor ");     break;
112         }
113
114         switch (info->flash_id & FLASH_TYPEMASK) {
115         case FLASH_28F640C3T:   printf ("28F640C3T (64 Mbit x 2, 128 x 128k)\n");
116                                 break;
117         default:                printf ("Unknown Chip Type\n");
118                                 break;
119         }
120
121         printf ("  Size: %ld MB in %d Sectors\n",
122                 info->size >> 20, info->sector_count);
123
124         printf ("  Sector Start Addresses:");
125         for (i=0; i<info->sector_count; ++i) {
126                 if ((i % 5) == 0)
127                         printf ("\n   ");
128                 printf (" %08lX%s",
129                         info->start[i],
130                         info->protect[i] ? " (RO)" : "     "
131                 );
132         }
133         printf ("\n");
134 }
135
136 /*
137  * The following code cannot be run from FLASH!
138  */
139
140 static ulong flash_get_size (vu_long *addr, flash_info_t *info)
141 {
142         short i;
143         ulong value;
144         ulong base = (ulong)addr;
145         ulong sector_offset;
146
147 #ifdef DEBUG
148         printf("Check flash at 0x%08x\n",(uint)addr);
149 #endif
150         /* Write "Intelligent Identifier" command: read Manufacturer ID */
151         *addr = 0x90909090;
152         udelay(20);
153         asm("sync");
154
155         value = addr[0] & 0x00FF00FF;
156
157 #ifdef DEBUG
158         printf("manufacturer=0x%x\n",(uint)value);
159 #endif
160         switch (value) {
161         case MT_MANUFACT:       /* SHARP, MT or => Intel */
162         case INTEL_ALT_MANU:
163                 info->flash_id = FLASH_MAN_INTEL;
164                 break;
165         default:
166                 printf("unknown manufacturer: %x\n", (unsigned int)value);
167                 info->flash_id = FLASH_UNKNOWN;
168                 info->sector_count = 0;
169                 info->size = 0;
170                 return (0);                     /* no or unknown flash  */
171         }
172
173         value = addr[1];             /* device ID            */
174
175 #ifdef DEBUG
176         printf("deviceID=0x%x\n",(uint)value);
177 #endif
178         switch (value) {
179
180         case (INTEL_ID_28F640C3T):
181                 info->flash_id += FLASH_28F640C3T;
182                 info->sector_count = 135;
183                 info->size = 0x01000000;
184                 sector_offset = 0x20000;
185                 break;                          /* => 2x8 MB            */
186
187         default:
188                 info->flash_id = FLASH_UNKNOWN;
189                 return (0);                     /* => no or unknown flash */
190
191         }
192
193         /* set up sector start address table
194          * The first 127 blocks are large, the last 8 are small.
195          */
196         for (i = 0; i < 127; i++) {
197                 info->start[i] = base;
198                 base += sector_offset;
199                 /* Sectors are locked upon reset */
200                 info->protect[i] = 0;
201         }
202         for (i = 127; i < 135; i++) {
203                 info->start[i] = base;
204                 base += 0x4000;
205                 /* Sectors are locked upon reset */
206                 info->protect[i] = 0;
207         }
208
209
210         /*
211          * Prevent writes to uninitialized FLASH.
212          */
213         if (info->flash_id != FLASH_UNKNOWN) {
214                 addr = (vu_long *)info->start[0];
215                 *addr = 0xFFFFFF;       /* reset bank to read array mode */
216                 asm("sync");
217         }
218
219         return (info->size);
220 }
221
222
223 /*-----------------------------------------------------------------------
224  */
225
226 int     flash_erase (flash_info_t *info, int s_first, int s_last)
227 {
228         int flag, prot, sect;
229         ulong start, now, last;
230
231         if ((s_first < 0) || (s_first > s_last)) {
232                 if (info->flash_id == FLASH_UNKNOWN) {
233                         printf ("- missing\n");
234                 } else {
235                         printf ("- no sectors to erase\n");
236                 }
237                 return 1;
238         }
239
240         if (    ((info->flash_id & FLASH_VENDMASK) != FLASH_MAN_INTEL)
241              && ((info->flash_id & FLASH_VENDMASK) != FLASH_MAN_SHARP) ) {
242                 printf ("Can't erase unknown flash type %08lx - aborted\n",
243                         info->flash_id);
244                 return 1;
245         }
246
247         prot = 0;
248         for (sect=s_first; sect<=s_last; ++sect) {
249                 if (info->protect[sect]) {
250                         prot++;
251                 }
252         }
253
254         if (prot) {
255                 printf ("- Warning: %d protected sectors will not be erased!\n",
256                         prot);
257         } else {
258                 printf ("\n");
259         }
260
261 #ifdef DEBUG
262         printf("\nFlash Erase:\n");
263 #endif
264         /* Make Sure Block Lock Bit is not set. */
265         if(clear_block_lock_bit((vu_long *)(info->start[s_first]))){
266                 return 1;
267         }
268
269         /* Start erase on unprotected sectors */
270 #if defined(DEBUG)
271         printf("Begin to erase now,s_first=0x%x s_last=0x%x...\n",s_first,s_last);
272 #endif
273         for (sect = s_first; sect<=s_last; sect++) {
274                 if (info->protect[sect] == 0) { /* not protected */
275                         vu_long *addr = (vu_long *)(info->start[sect]);
276                         asm("sync");
277
278                         last = start = get_timer (0);
279
280                         /* Disable interrupts which might cause a timeout here */
281                         flag = disable_interrupts();
282
283                         /* Reset Array */
284                         *addr = 0xffffffff;
285                         asm("sync");
286                         /* Clear Status Register */
287                         *addr = 0x50505050;
288                         asm("sync");
289                         /* Single Block Erase Command */
290                         *addr = 0x20202020;
291                         asm("sync");
292                         /* Confirm */
293                         *addr = 0xD0D0D0D0;
294                         asm("sync");
295
296                         if((info->flash_id & FLASH_TYPEMASK) != FLASH_LH28F016SCT) {
297                             /* Resume Command, as per errata update */
298                             *addr = 0xD0D0D0D0;
299                             asm("sync");
300                         }
301
302                         /* re-enable interrupts if necessary */
303                         if (flag)
304                                 enable_interrupts();
305
306                         /* wait at least 80us - let's wait 1 ms */
307                         udelay (1000);
308                         while ((*addr & 0x00800080) != 0x00800080) {
309                                 if(*addr & 0x00200020){
310                                         printf("Error in Block Erase - Lock Bit may be set!\n");
311                                         printf("Status Register = 0x%X\n", (uint)*addr);
312                                         *addr = 0xFFFFFFFF;     /* reset bank */
313                                         asm("sync");
314                                         return 1;
315                                 }
316                                 if ((now=get_timer(start)) > CONFIG_SYS_FLASH_ERASE_TOUT) {
317                                         printf ("Timeout\n");
318                                         *addr = 0xFFFFFFFF;     /* reset bank */
319                                         asm("sync");
320                                         return 1;
321                                 }
322                                 /* show that we're waiting */
323                                 if ((now - last) > 1000) {      /* every second */
324                                         putc ('.');
325                                         last = now;
326                                 }
327                         }
328
329                         /* reset to read mode */
330                         *addr = 0xFFFFFFFF;
331                         asm("sync");
332                 }
333         }
334
335         printf ("flash erase done\n");
336         return 0;
337 }
338
339 /*-----------------------------------------------------------------------
340  * Copy memory to flash, returns:
341  * 0 - OK
342  * 1 - write timeout
343  * 2 - Flash not erased
344  */
345
346 int write_buff (flash_info_t *info, uchar *src, ulong addr, ulong cnt)
347 {
348         ulong cp, wp, data;
349         int i, l, rc;
350
351         wp = (addr & ~3);       /* get lower word aligned address */
352
353         /*
354          * handle unaligned start bytes
355          */
356         if ((l = addr - wp) != 0) {
357                 data = 0;
358                 for (i=0, cp=wp; i<l; ++i, ++cp) {
359                         data = (data << 8) | (*(uchar *)cp);
360                 }
361                 for (; i<4 && cnt>0; ++i) {
362                         data = (data << 8) | *src++;
363                         --cnt;
364                         ++cp;
365                 }
366                 for (; cnt==0 && i<4; ++i, ++cp) {
367                         data = (data << 8) | (*(uchar *)cp);
368                 }
369
370                 if ((rc = write_word(info, wp, data)) != 0) {
371                         return (rc);
372                 }
373                 wp += 4;
374         }
375
376         /*
377          * handle word aligned part
378          */
379         while (cnt >= 4) {
380                 data = 0;
381                 for (i=0; i<4; ++i) {
382                         data = (data << 8) | *src++;
383                 }
384                 if ((rc = write_word(info, wp, data)) != 0) {
385                         return (rc);
386                 }
387                 wp  += 4;
388                 cnt -= 4;
389         }
390
391         if (cnt == 0) {
392                 return (0);
393         }
394
395         /*
396          * handle unaligned tail bytes
397          */
398         data = 0;
399         for (i=0, cp=wp; i<4 && cnt>0; ++i, ++cp) {
400                 data = (data << 8) | *src++;
401                 --cnt;
402         }
403         for (; i<4; ++i, ++cp) {
404                 data = (data << 8) | (*(uchar *)cp);
405         }
406
407         return (write_word(info, wp, data));
408 }
409
410 /*-----------------------------------------------------------------------
411  * Write a word to Flash, returns:
412  * 0 - OK
413  * 1 - write timeout
414  * 2 - Flash not erased
415  */
416 static int write_word (flash_info_t *info, ulong dest, ulong data)
417 {
418         vu_long *addr = (vu_long *)dest;
419         ulong start, csr;
420         int flag;
421
422         /* Check if Flash is (sufficiently) erased */
423         if ((*addr & data) != data) {
424                 return (2);
425         }
426         /* Disable interrupts which might cause a timeout here */
427         flag = disable_interrupts();
428
429         /* Write Command */
430         *addr = 0x10101010;
431         asm("sync");
432
433         /* Write Data */
434         *addr = data;
435
436         /* re-enable interrupts if necessary */
437         if (flag)
438                 enable_interrupts();
439
440         /* data polling for D7 */
441         start = get_timer (0);
442         flag  = 0;
443
444         while (((csr = *addr) & 0x00800080) != 0x00800080) {
445                 if (get_timer(start) > CONFIG_SYS_FLASH_WRITE_TOUT) {
446                         flag = 1;
447                         break;
448                 }
449         }
450         if (csr & 0x40404040) {
451                 printf ("CSR indicates write error (%08lx) at %08lx\n", csr, (ulong)addr);
452                 flag = 1;
453         }
454
455         /* Clear Status Registers Command */
456         *addr = 0x50505050;
457         asm("sync");
458         /* Reset to read array mode */
459         *addr = 0xFFFFFFFF;
460         asm("sync");
461
462         return (flag);
463 }
464
465 /*-----------------------------------------------------------------------
466  * Clear Block Lock Bit, returns:
467  * 0 - OK
468  * 1 - Timeout
469  */
470
471 static int clear_block_lock_bit(vu_long  * addr)
472 {
473         ulong start, now;
474
475         /* Reset Array */
476         *addr = 0xffffffff;
477         asm("sync");
478         /* Clear Status Register */
479         *addr = 0x50505050;
480         asm("sync");
481
482         *addr = 0x60606060;
483         asm("sync");
484         *addr = 0xd0d0d0d0;
485         asm("sync");
486
487         start = get_timer (0);
488         while((*addr & 0x00800080) != 0x00800080){
489                 if ((now=get_timer(start)) > CONFIG_SYS_FLASH_ERASE_TOUT) {
490                         printf ("Timeout on clearing Block Lock Bit\n");
491                         *addr = 0xFFFFFFFF;     /* reset bank */
492                         asm("sync");
493                         return 1;
494                 }
495         }
496         return 0;
497 }
498
499 #endif /* !CONFIG_SYS_NO_FLASH */