]> git.kernelconcepts.de Git - karo-tx-uboot.git/blob - board/lpd7a40x/flash.c
ARM: remove broken "edb93xx" boards
[karo-tx-uboot.git] / board / lpd7a40x / flash.c
1 /*
2  * (C) Copyright 2002
3  * Sysgo Real-Time Solutions, GmbH <www.elinos.com>
4  * Marius Groeger <mgroeger@sysgo.de>
5  *
6  * (C) Copyright 2002
7  * Gary Jennejohn, DENX Software Engineering, <garyj@denx.de>
8  *
9  * See file CREDITS for list of people who contributed to this
10  * project.
11  *
12  * This program is free software; you can redistribute it and/or
13  * modify it under the terms of the GNU General Public License as
14  * published by the Free Software Foundation; either version 2 of
15  * the License, or (at your option) any later version.
16  *
17  * This program is distributed in the hope that it will be useful,
18  * but WITHOUT ANY WARRANTY; without even the implied warranty of
19  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
20  * GNU General Public License for more details.
21  *
22  * You should have received a copy of the GNU General Public License
23  * along with this program; if not, write to the Free Software
24  * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
25  * MA 02111-1307 USA
26  */
27
28 /* #define DEBUG */
29
30 #include <common.h>
31 #include <environment.h>
32
33 #define FLASH_BANK_SIZE 0x1000000       /* 16MB (2 x 8 MB) */
34 #define MAIN_SECT_SIZE  0x40000         /* 256KB (2 x 128kB) */
35
36 flash_info_t flash_info[CONFIG_SYS_MAX_FLASH_BANKS];
37
38
39 #define CMD_READ_ARRAY          0x00FF00FF
40 #define CMD_IDENTIFY            0x00900090
41 #define CMD_ERASE_SETUP         0x00200020
42 #define CMD_ERASE_CONFIRM       0x00D000D0
43 #define CMD_PROGRAM             0x00400040
44 #define CMD_RESUME              0x00D000D0
45 #define CMD_SUSPEND             0x00B000B0
46 #define CMD_STATUS_READ         0x00700070
47 #define CMD_STATUS_RESET        0x00500050
48
49 #define BIT_BUSY                0x00800080
50 #define BIT_ERASE_SUSPEND       0x00400040
51 #define BIT_ERASE_ERROR         0x00200020
52 #define BIT_PROGRAM_ERROR       0x00100010
53 #define BIT_VPP_RANGE_ERROR     0x00080008
54 #define BIT_PROGRAM_SUSPEND     0x00040004
55 #define BIT_PROTECT_ERROR       0x00020002
56 #define BIT_UNDEFINED           0x00010001
57
58 #define BIT_SEQUENCE_ERROR      0x00300030
59 #define BIT_TIMEOUT             0x80000000
60
61 /*-----------------------------------------------------------------------
62  */
63
64 ulong flash_init (void)
65 {
66         int i, j;
67         ulong size = 0;
68
69         for (i = 0; i < CONFIG_SYS_MAX_FLASH_BANKS; i++) {
70                 ulong flashbase = 0;
71
72                 flash_info[i].flash_id =
73                         (INTEL_MANUFACT     & FLASH_VENDMASK) |
74                         (INTEL_ID_28F640J3A & FLASH_TYPEMASK);
75                 flash_info[i].size = FLASH_BANK_SIZE;
76                 flash_info[i].sector_count = CONFIG_SYS_MAX_FLASH_SECT;
77                 memset (flash_info[i].protect, 0, CONFIG_SYS_MAX_FLASH_SECT);
78                 if (i == 0)
79                         flashbase = CONFIG_SYS_FLASH_BASE;
80                 else
81                         panic ("configured too many flash banks!\n");
82                 for (j = 0; j < flash_info[i].sector_count; j++) {
83                         flash_info[i].start[j] = flashbase;
84
85                         /* uniform sector size */
86                         flashbase += MAIN_SECT_SIZE;
87                 }
88                 size += flash_info[i].size;
89         }
90
91         /*
92          * Protect monitor and environment sectors
93          */
94         flash_protect ( FLAG_PROTECT_SET,
95                         CONFIG_SYS_FLASH_BASE,
96                         CONFIG_SYS_FLASH_BASE + monitor_flash_len - 1,
97                         &flash_info[0]);
98
99         flash_protect ( FLAG_PROTECT_SET,
100                         CONFIG_ENV_ADDR,
101                         CONFIG_ENV_ADDR + CONFIG_ENV_SECT_SIZE - 1, &flash_info[0]);
102
103 #ifdef CONFIG_ENV_ADDR_REDUND
104         flash_protect ( FLAG_PROTECT_SET,
105                         CONFIG_ENV_ADDR_REDUND,
106                         CONFIG_ENV_ADDR_REDUND + CONFIG_ENV_SECT_SIZE - 1,
107                         &flash_info[0]);
108 #endif
109
110         return size;
111 }
112
113 /*-----------------------------------------------------------------------
114  */
115 void flash_print_info (flash_info_t * info)
116 {
117         int i;
118
119         switch (info->flash_id & FLASH_VENDMASK) {
120         case (INTEL_MANUFACT & FLASH_VENDMASK):
121                 printf ("Intel: ");
122                 break;
123         default:
124                 printf ("Unknown Vendor ");
125                 break;
126         }
127
128         switch (info->flash_id & FLASH_TYPEMASK) {
129         case (INTEL_ID_28F640J3A & FLASH_TYPEMASK):
130                 printf ("2x 28F640J3A (64Mbit)\n");
131                 break;
132         default:
133                 printf ("Unknown Chip Type\n");
134                 return;
135                 break;
136         }
137
138         printf ("  Size: %ld MB in %d Sectors\n",
139                         info->size >> 20, info->sector_count);
140
141         printf ("  Sector Start Addresses:");
142         for (i = 0; i < info->sector_count; i++) {
143                 if ((i % 5) == 0) {
144                         printf ("\n   ");
145                 }
146                 printf (" %08lX%s",
147                         info->start[i],
148                         info->protect[i] ? " (RO)" : "     ");
149         }
150         printf ("\n");
151 }
152
153 /*-----------------------------------------------------------------------
154  */
155
156 int flash_error (ulong code)
157 {
158         /* Check bit patterns */
159         /* SR.7=0 is busy, SR.7=1 is ready */
160         /* all other flags indicate error on 1 */
161         /* SR.0 is undefined */
162         /* Timeout is our faked flag */
163
164         /* sequence is described in Intel 290644-005 document */
165
166         /* check Timeout */
167         if (code & BIT_TIMEOUT) {
168                 puts ("Timeout\n");
169                 return ERR_TIMOUT;
170         }
171
172         /* check Busy, SR.7 */
173         if (~code & BIT_BUSY) {
174                 puts ("Busy\n");
175                 return ERR_PROG_ERROR;
176         }
177
178         /* check Vpp low, SR.3 */
179         if (code & BIT_VPP_RANGE_ERROR) {
180                 puts ("Vpp range error\n");
181                 return ERR_PROG_ERROR;
182         }
183
184         /* check Device Protect Error, SR.1 */
185         if (code & BIT_PROTECT_ERROR) {
186                 puts ("Device protect error\n");
187                 return ERR_PROG_ERROR;
188         }
189
190         /* check Command Seq Error, SR.4 & SR.5 */
191         if (code & BIT_SEQUENCE_ERROR) {
192                 puts ("Command seqence error\n");
193                 return ERR_PROG_ERROR;
194         }
195
196         /* check Block Erase Error, SR.5 */
197         if (code & BIT_ERASE_ERROR) {
198                 puts ("Block erase error\n");
199                 return ERR_PROG_ERROR;
200         }
201
202         /* check Program Error, SR.4 */
203         if (code & BIT_PROGRAM_ERROR) {
204                 puts ("Program error\n");
205                 return ERR_PROG_ERROR;
206         }
207
208         /* check Block Erase Suspended, SR.6 */
209         if (code & BIT_ERASE_SUSPEND) {
210                 puts ("Block erase suspended\n");
211                 return ERR_PROG_ERROR;
212         }
213
214         /* check Program Suspended, SR.2 */
215         if (code & BIT_PROGRAM_SUSPEND) {
216                 puts ("Program suspended\n");
217                 return ERR_PROG_ERROR;
218         }
219
220         /* OK, no error */
221         return ERR_OK;
222 }
223
224 /*-----------------------------------------------------------------------
225  */
226
227 int flash_erase (flash_info_t * info, int s_first, int s_last)
228 {
229         ulong result, result1;
230         int iflag, prot, sect;
231         int rc = ERR_OK;
232         ulong start;
233
234 #ifdef USE_920T_MMU
235         int cflag;
236 #endif
237
238         debug ("flash_erase: s_first %d  s_last %d\n", s_first, s_last);
239
240         /* first look for protection bits */
241
242         if (info->flash_id == FLASH_UNKNOWN)
243                 return ERR_UNKNOWN_FLASH_TYPE;
244
245         if ((s_first < 0) || (s_first > s_last)) {
246                 return ERR_INVAL;
247         }
248
249         if ((info->flash_id & FLASH_VENDMASK) !=
250                 (INTEL_MANUFACT & FLASH_VENDMASK)) {
251                 return ERR_UNKNOWN_FLASH_VENDOR;
252         }
253
254         prot = 0;
255         for (sect = s_first; sect <= s_last; ++sect) {
256                 if (info->protect[sect]) {
257                         prot++;
258                 }
259         }
260
261         if (prot) {
262                 printf ("- Warning: %d protected sectors will not be erased!\n",
263                         prot);
264         } else {
265                 printf ("\n");
266         }
267
268         /*
269          * Disable interrupts which might cause a timeout
270          * here. Remember that our exception vectors are
271          * at address 0 in the flash, and we don't want a
272          * (ticker) exception to happen while the flash
273          * chip is in programming mode.
274          */
275 #ifdef USE_920T_MMU
276         cflag = dcache_status ();
277         dcache_disable ();
278 #endif
279         iflag = disable_interrupts ();
280
281         /* Start erase on unprotected sectors */
282         for (sect = s_first; sect <= s_last && !ctrlc (); sect++) {
283
284                 debug ("Erasing sector %2d @ %08lX... ",
285                         sect, info->start[sect]);
286
287                 /* arm simple, non interrupt dependent timer */
288                 start = get_timer(0);
289
290                 if (info->protect[sect] == 0) { /* not protected */
291                         vu_long *addr = (vu_long *) (info->start[sect]);
292                         ulong bsR7, bsR7_2, bsR5, bsR5_2;
293
294                         /* *addr = CMD_STATUS_RESET; */
295                         *addr = CMD_ERASE_SETUP;
296                         *addr = CMD_ERASE_CONFIRM;
297
298                         /* wait until flash is ready */
299                         do {
300                                 /* check timeout */
301                                 if (get_timer(start) > CONFIG_SYS_FLASH_ERASE_TOUT) {
302                                         *addr = CMD_STATUS_RESET;
303                                         result = BIT_TIMEOUT;
304                                         break;
305                                 }
306
307                                 *addr = CMD_STATUS_READ;
308                                 result = *addr;
309                                 bsR7 = result & (1 << 7);
310                                 bsR7_2 = result & (1 << 23);
311                         } while (!bsR7 | !bsR7_2);
312
313                         *addr = CMD_STATUS_READ;
314                         result1 = *addr;
315                         bsR5 = result1 & (1 << 5);
316                         bsR5_2 = result1 & (1 << 21);
317 #ifdef SAMSUNG_FLASH_DEBUG
318                         printf ("bsR5 %lx bsR5_2 %lx\n", bsR5, bsR5_2);
319                         if (bsR5 != 0 && bsR5_2 != 0)
320                                 printf ("bsR5 %lx bsR5_2 %lx\n", bsR5, bsR5_2);
321 #endif
322
323                         *addr = CMD_READ_ARRAY;
324                         *addr = CMD_RESUME;
325
326                         if ((rc = flash_error (result)) != ERR_OK)
327                                 goto outahere;
328 #if 0
329                         printf ("ok.\n");
330                 } else {                /* it was protected */
331
332                         printf ("protected!\n");
333 #endif
334                 }
335         }
336
337 outahere:
338         /* allow flash to settle - wait 10 ms */
339         udelay_masked (10000);
340
341         if (iflag)
342                 enable_interrupts ();
343
344 #ifdef USE_920T_MMU
345         if (cflag)
346                 dcache_enable ();
347 #endif
348         return rc;
349 }
350
351 /*-----------------------------------------------------------------------
352  * Copy memory to flash
353  */
354
355 static int write_word (flash_info_t * info, ulong dest, ulong data)
356 {
357         vu_long *addr = (vu_long *) dest;
358         ulong result;
359         int rc = ERR_OK;
360         int iflag;
361         ulong start;
362
363 #ifdef USE_920T_MMU
364         int cflag;
365 #endif
366
367         /*
368          * Check if Flash is (sufficiently) erased
369          */
370         result = *addr;
371         if ((result & data) != data)
372                 return ERR_NOT_ERASED;
373
374         /*
375          * Disable interrupts which might cause a timeout
376          * here. Remember that our exception vectors are
377          * at address 0 in the flash, and we don't want a
378          * (ticker) exception to happen while the flash
379          * chip is in programming mode.
380          */
381 #ifdef USE_920T_MMU
382         cflag = dcache_status ();
383         dcache_disable ();
384 #endif
385         iflag = disable_interrupts ();
386
387         /* *addr = CMD_STATUS_RESET; */
388         *addr = CMD_PROGRAM;
389         *addr = data;
390
391         /* arm simple, non interrupt dependent timer */
392         start = get_timer(0);
393
394         /* wait until flash is ready */
395         do {
396                 /* check timeout */
397                 if (get_timer(start) > CONFIG_SYS_FLASH_ERASE_TOUT) {
398                         *addr = CMD_SUSPEND;
399                         result = BIT_TIMEOUT;
400                         break;
401                 }
402
403                 *addr = CMD_STATUS_READ;
404                 result = *addr;
405         } while (~result & BIT_BUSY);
406
407         /* *addr = CMD_READ_ARRAY; */
408         *addr = CMD_STATUS_READ;
409         result = *addr;
410
411         rc = flash_error (result);
412
413         if (iflag)
414                 enable_interrupts ();
415
416 #ifdef USE_920T_MMU
417         if (cflag)
418                 dcache_enable ();
419 #endif
420         *addr = CMD_READ_ARRAY;
421         *addr = CMD_RESUME;
422         return rc;
423 }
424
425 /*-----------------------------------------------------------------------
426  * Copy memory to flash.
427  */
428
429 int write_buff (flash_info_t * info, uchar * src, ulong addr, ulong cnt)
430 {
431         ulong cp, wp, data;
432         int l;
433         int i, rc;
434
435         wp = (addr & ~3);                       /* get lower word aligned address */
436
437         /*
438          * handle unaligned start bytes
439          */
440         if ((l = addr - wp) != 0) {
441                 data = 0;
442                 for (i = 0, cp = wp; i < l; ++i, ++cp) {
443                         data = (data >> 8) | (*(uchar *) cp << 24);
444                 }
445                 for (; i < 4 && cnt > 0; ++i) {
446                         data = (data >> 8) | (*src++ << 24);
447                         --cnt;
448                         ++cp;
449                 }
450                 for (; cnt == 0 && i < 4; ++i, ++cp) {
451                         data = (data >> 8) | (*(uchar *) cp << 24);
452                 }
453
454                 if ((rc = write_word (info, wp, data)) != 0) {
455                         return (rc);
456                 }
457                 wp += 4;
458         }
459
460         /*
461          * handle word aligned part
462          */
463         while (cnt >= 4) {
464                 data = *((vu_long *) src);
465                 if ((rc = write_word (info, wp, data)) != 0) {
466                         return (rc);
467                 }
468                 src += 4;
469                 wp += 4;
470                 cnt -= 4;
471         }
472
473         if (cnt == 0) {
474                 return ERR_OK;
475         }
476
477         /*
478          * handle unaligned tail bytes
479          */
480         data = 0;
481         for (i = 0, cp = wp; i < 4 && cnt > 0; ++i, ++cp) {
482                 data = (data >> 8) | (*src++ << 24);
483                 --cnt;
484         }
485         for (; i < 4; ++i, ++cp) {
486                 data = (data >> 8) | (*(uchar *) cp << 24);
487         }
488
489         return write_word (info, wp, data);
490 }