]> git.kernelconcepts.de Git - karo-tx-uboot.git/blob - board/a3000/flash.c
Merge git://git.denx.de/u-boot-arm
[karo-tx-uboot.git] / board / a3000 / 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
9 #include <common.h>
10 #include <mpc824x.h>
11
12 #if defined(CONFIG_ENV_IS_IN_FLASH)
13 # ifndef  CONFIG_ENV_ADDR
14 #  define CONFIG_ENV_ADDR  (CONFIG_SYS_FLASH_BASE + CONFIG_ENV_OFFSET)
15 # endif
16 # ifndef  CONFIG_ENV_SIZE
17 #  define CONFIG_ENV_SIZE  CONFIG_ENV_SECT_SIZE
18 # endif
19 # ifndef  CONFIG_ENV_SECT_SIZE
20 #  define CONFIG_ENV_SECT_SIZE  CONFIG_ENV_SIZE
21 # endif
22 #endif
23
24
25 /*---------------------------------------------------------------------*/
26 #define DEBUG_FLASH
27
28 #ifdef DEBUG_FLASH
29 #define DEBUGF(fmt,args...) printf(fmt ,##args)
30 #else
31 #define DEBUGF(fmt,args...)
32 #endif
33 /*---------------------------------------------------------------------*/
34
35 flash_info_t    flash_info[CONFIG_SYS_MAX_FLASH_BANKS]; /* info for FLASH chips */
36
37 /*-----------------------------------------------------------------------
38  * Functions
39  */
40 static ulong flash_get_size (vu_char *addr, flash_info_t *info);
41 static int write_data (flash_info_t *info, uchar *dest, uchar data);
42 static void flash_get_offsets (ulong base, flash_info_t *info);
43
44 #define BS(b)     (b)
45 #define BYTEME(x) ((x) & 0xFF)
46
47 /*-----------------------------------------------------------------------
48  */
49
50 unsigned long flash_init (void)
51 {
52         unsigned long flash_banks[CONFIG_SYS_MAX_FLASH_BANKS] = CONFIG_SYS_FLASH_BANKS;
53         unsigned long size, size_b[CONFIG_SYS_MAX_FLASH_BANKS];
54
55         int i;
56
57         /* Init: no FLASHes known */
58         for (i=0; i<CONFIG_SYS_MAX_FLASH_BANKS; ++i)
59         {
60                 flash_info[i].flash_id = FLASH_UNKNOWN;
61
62                 DEBUGF("Get flash bank %d @ 0x%08lx\n", i, flash_banks[i]);
63 /*
64                 size_b[i] = flash_get_size((vu_char *)flash_banks[i], &flash_info[i]);
65 */
66                 size_b[i] = flash_get_size((vu_char *) 0xff800000 , &flash_info[i]);
67
68                 if (flash_info[i].flash_id == FLASH_UNKNOWN)
69                 {
70                         printf ("## Unknown FLASH on Bank %d: "
71                                 "ID 0x%lx, Size = 0x%08lx = %ld MB\n",
72                                 i, flash_info[i].flash_id,
73                                 size_b[i], size_b[i]<<20);
74                 }
75                 else
76                 {
77                         DEBUGF("## Flash bank %d at 0x%08lx sizes: 0x%08lx \n",
78                                 i, flash_banks[i], size_b[i]);
79
80                         flash_get_offsets (flash_banks[i], &flash_info[i]);
81                         flash_info[i].size = size_b[i];
82                 }
83         }
84
85
86 #if CONFIG_SYS_MONITOR_BASE >= CONFIG_SYS_FLASH_BASE
87         DEBUGF("protect monitor %x @ %x\n", CONFIG_SYS_MONITOR_BASE, CONFIG_SYS_MONITOR_LEN);
88         /* monitor protection ON by default */
89         flash_protect(FLAG_PROTECT_SET,
90                       CONFIG_SYS_MONITOR_BASE,
91                       CONFIG_SYS_MONITOR_BASE+CONFIG_SYS_MONITOR_LEN-1,
92                       &flash_info[0]);
93 #endif
94
95 #ifdef  CONFIG_ENV_IS_IN_FLASH
96         /* ENV protection ON by default */
97         DEBUGF("protect environtment %x @ %x\n", CONFIG_ENV_ADDR, CONFIG_ENV_SECT_SIZE);
98         flash_protect(FLAG_PROTECT_SET,
99                       CONFIG_ENV_ADDR,
100                       CONFIG_ENV_ADDR+CONFIG_ENV_SECT_SIZE-1,
101                       &flash_info[0]);
102 #endif
103
104         size = 0;
105         DEBUGF("## Final Flash bank sizes: ");
106         for (i=0; i<CONFIG_SYS_MAX_FLASH_BANKS; ++i)
107         {
108                 DEBUGF("%08lx ", size_b[i]);
109                 size += size_b[i];
110         }
111         DEBUGF("\n");
112         return (size);
113 }
114
115 /*-----------------------------------------------------------------------
116  */
117 static void flash_get_offsets (ulong base, flash_info_t *info)
118 {
119         int i;
120
121         if (info->flash_id == FLASH_UNKNOWN) {
122                 return;
123         }
124
125         switch (info->flash_id & FLASH_VENDMASK) {
126                 case FLASH_MAN_INTEL:
127                     for (i = 0; i < info->sector_count; i++) {
128                                 info->start[i] = base;
129                                 base += 0x00020000;             /* 128k per bank */
130                     }
131                     return;
132
133                 default:
134                     printf ("Don't know sector ofsets for flash type 0x%lx\n", info->flash_id);
135                     return;
136         }
137 }
138
139 /*-----------------------------------------------------------------------
140  */
141 void flash_print_info  (flash_info_t *info)
142 {
143         int i;
144
145         if (info->flash_id == FLASH_UNKNOWN) {
146                 printf ("missing or unknown FLASH type\n");
147                 return;
148         }
149
150         switch (info->flash_id & FLASH_VENDMASK) {
151         case FLASH_MAN_AMD:     printf ("AMD ");                break;
152         case FLASH_MAN_FUJ:     printf ("Fujitsu ");            break;
153         case FLASH_MAN_SST:     printf ("SST ");                break;
154         case FLASH_MAN_STM:     printf ("STM ");                break;
155         case FLASH_MAN_INTEL:   printf ("Intel ");              break;
156         case FLASH_MAN_MT:      printf ("MT ");                 break;
157         default:                printf ("Unknown Vendor ");     break;
158         }
159
160         switch (info->flash_id & FLASH_TYPEMASK) {
161         case FLASH_28F320J3A:
162                         printf ("28F320J3A (32Mbit = 128K x 32)\n");
163                         break;
164         case FLASH_28F640J3A:
165                         printf ("28F640J3A (64Mbit = 128K x 64)\n");
166                         break;
167         case FLASH_28F128J3A:
168                         printf ("28F128J3A (128Mbit = 128K x 128)\n");
169                         break;
170         default:
171                         printf ("Unknown Chip Type\n");
172                         break;
173         }
174
175 #if 1
176         if (info->size >= (1 << 20)) {
177                 i = 20;
178         } else {
179                 i = 10;
180         }
181         printf ("  Size: %ld %cB in %d Sectors\n",
182                 info->size >> i,
183                 (i == 20) ? 'M' : 'k',
184                 info->sector_count);
185
186         printf ("  Sector Start Addresses:");
187         for (i=0; i<info->sector_count; ++i) {
188                 if ((i % 5) == 0)
189                         printf ("\n   ");
190                 printf (" %08lX%s",
191                         info->start[i],
192                         info->protect[i] ? " (RO)" : "     "
193                 );
194         }
195         printf ("\n");
196 #endif
197         return;
198 }
199
200 /*-----------------------------------------------------------------------
201  */
202
203
204 /*-----------------------------------------------------------------------
205  */
206
207 /*
208  * The following code cannot be run from FLASH!
209  */
210 static ulong flash_get_size (vu_char *addr, flash_info_t *info)
211 {
212         vu_char manuf, device;
213
214         addr[0] = BS(0x90);
215         manuf = BS(addr[0]);
216         DEBUGF("Manuf. ID @ 0x%08lx: 0x%08x\n", (ulong)addr, manuf);
217
218         switch (manuf) {
219         case BYTEME(AMD_MANUFACT):
220                 info->flash_id = FLASH_MAN_AMD;
221                 break;
222         case BYTEME(FUJ_MANUFACT):
223                 info->flash_id = FLASH_MAN_FUJ;
224                 break;
225         case BYTEME(SST_MANUFACT):
226                 info->flash_id = FLASH_MAN_SST;
227                 break;
228         case BYTEME(STM_MANUFACT):
229                 info->flash_id = FLASH_MAN_STM;
230                 break;
231         case BYTEME(INTEL_MANUFACT):
232                 info->flash_id = FLASH_MAN_INTEL;
233                 break;
234         default:
235                 info->flash_id = FLASH_UNKNOWN;
236                 info->sector_count = 0;
237                 info->size = 0;
238                 addr[0] = BS(0xFF);             /* restore read mode, (yes, BS is a NOP) */
239                 return 0;                       /* no or unknown flash  */
240         }
241
242         device = BS(addr[2]);                   /* device ID            */
243
244         DEBUGF("Device ID @ 0x%08lx: 0x%08x\n", (ulong)(&addr[1]), device);
245
246         switch (device) {
247         case BYTEME(INTEL_ID_28F320J3A):
248                 info->flash_id += FLASH_28F320J3A;
249                 info->sector_count = 32;
250                 info->size = 0x00400000;
251                 break;                          /* =>  4 MB             */
252
253         case BYTEME(INTEL_ID_28F640J3A):
254                 info->flash_id += FLASH_28F640J3A;
255                 info->sector_count = 64;
256                 info->size = 0x00800000;
257                 break;                          /* => 8 MB              */
258
259         case BYTEME(INTEL_ID_28F128J3A):
260                 info->flash_id += FLASH_28F128J3A;
261                 info->sector_count = 128;
262                 info->size = 0x01000000;
263                 break;                          /* => 16 MB             */
264
265         default:
266                 info->flash_id = FLASH_UNKNOWN;
267                 addr[0] = BS(0xFF);             /* restore read mode (yes, a NOP) */
268                 return 0;                       /* => no or unknown flash */
269
270         }
271
272         if (info->sector_count > CONFIG_SYS_MAX_FLASH_SECT) {
273                 printf ("** ERROR: sector count %d > max (%d) **\n",
274                         info->sector_count, CONFIG_SYS_MAX_FLASH_SECT);
275                 info->sector_count = CONFIG_SYS_MAX_FLASH_SECT;
276         }
277
278         addr[0] = BS(0xFF);             /* restore read mode */
279
280         return (info->size);
281 }
282
283
284 /*-----------------------------------------------------------------------
285  */
286
287 int     flash_erase (flash_info_t *info, int s_first, int s_last)
288 {
289         int flag, prot, sect;
290         ulong start, now, last;
291
292         if ((s_first < 0) || (s_first > s_last)) {
293                 if (info->flash_id == FLASH_UNKNOWN) {
294                         printf ("- missing\n");
295                 } else {
296                         printf ("- no sectors to erase\n");
297                 }
298                 return 1;
299         }
300
301         if ((info->flash_id & FLASH_VENDMASK) != FLASH_MAN_INTEL) {
302                 printf ("Can erase only Intel flash types - aborted\n");
303                 return 1;
304         }
305
306         prot = 0;
307         for (sect=s_first; sect<=s_last; ++sect) {
308                 if (info->protect[sect]) {
309                         prot++;
310                 }
311         }
312
313         if (prot) {
314                 printf ("- Warning: %d protected sectors will not be erased!\n", prot);
315         } else {
316                 printf ("\n");
317         }
318
319         start = get_timer (0);
320         last  = start;
321         /* Start erase on unprotected sectors */
322         for (sect = s_first; sect<=s_last; sect++) {
323                 if (info->protect[sect] == 0) { /* not protected */
324                         vu_char *addr = (vu_char *)(info->start[sect]);
325                         unsigned long status;
326
327                         /* Disable interrupts which might cause a timeout here */
328                         flag = disable_interrupts();
329
330                         *addr = BS(0x50);       /* clear status register */
331                         *addr = BS(0x20);       /* erase setup */
332                         *addr = BS(0xD0);       /* erase confirm */
333
334                         /* re-enable interrupts if necessary */
335                         if (flag) {
336                                 enable_interrupts();
337                         }
338
339                         /* wait at least 80us - let's wait 1 ms */
340                         udelay (1000);
341
342                         while (((status = BS(*addr)) & BYTEME(0x00800080)) != BYTEME(0x00800080)) {
343                                 if ((now=get_timer(start)) > CONFIG_SYS_FLASH_ERASE_TOUT) {
344                                         printf ("Timeout\n");
345                                         *addr = BS(0xB0); /* suspend erase        */
346                                         *addr = BS(0xFF); /* reset to read mode */
347                                         return 1;
348                                 }
349
350                                 /* show that we're waiting */
351                                 if ((now - last) > 1000) {      /* every second */
352                                         putc ('.');
353                                         last = now;
354                                 }
355                         }
356
357                         *addr = BS(0xFF);       /* reset to read mode */
358                 }
359         }
360         printf (" done\n");
361         return 0;
362 }
363
364 /*-----------------------------------------------------------------------
365  * Copy memory to flash, returns:
366  * 0 - OK
367  * 1 - write timeout
368  * 2 - Flash not erased
369  * 4 - Flash not identified
370  */
371
372 #define FLASH_WIDTH     1       /* flash bus width in bytes */
373
374 int write_buff (flash_info_t *info, uchar *src, ulong addr, ulong cnt)
375 {
376         uchar *wp = (uchar *)addr;
377         int rc;
378
379         if (info->flash_id == FLASH_UNKNOWN) {
380                 return 4;
381         }
382
383         while (cnt > 0) {
384                 if ((rc = write_data(info, wp, *src)) != 0) {
385                         return rc;
386                 }
387                 wp++;
388                 src++;
389                 cnt--;
390         }
391
392         return cnt;
393 }
394
395 /*-----------------------------------------------------------------------
396  * Write a word to Flash, returns:
397  * 0 - OK
398  * 1 - write timeout
399  * 2 - Flash not erased
400  */
401 static int write_data (flash_info_t *info, uchar *dest, uchar data)
402 {
403         vu_char *addr = (vu_char *)dest;
404         ulong status;
405         ulong start;
406         int flag;
407
408         /* Check if Flash is (sufficiently) erased */
409         if ((BS(*addr) & data) != data) {
410                 return 2;
411         }
412         /* Disable interrupts which might cause a timeout here */
413         flag = disable_interrupts();
414
415         *addr = BS(0x40);               /* write setup */
416         *addr = data;
417
418         /* re-enable interrupts if necessary */
419         if (flag) {
420                 enable_interrupts();
421         }
422
423         start = get_timer (0);
424
425         while (((status = BS(*addr)) & BYTEME(0x00800080)) != BYTEME(0x00800080)) {
426                 if (get_timer(start) > CONFIG_SYS_FLASH_WRITE_TOUT) {
427                         *addr = BS(0xFF);       /* restore read mode */
428                         return 1;
429                 }
430         }
431
432         *addr = BS(0xFF);       /* restore read mode */
433
434         return 0;
435 }
436
437 /*-----------------------------------------------------------------------
438  */