source: SVN/rincon/u-boot/board/netstar/flash.c @ 55

Last change on this file since 55 was 55, checked in by Tim Harvey, 22 months ago

rincon: added latest u-boot source

restored form server backup

Signed-off-by: Tim Harvey <tharvey@…>

File size: 7.6 KB
Line 
1/*
2 * (C) Copyright 2002
3 * Sysgo Real-Time Solutions, GmbH <www.elinos.com>
4 * Alex Zuepke <azu@sysgo.de>
5 *
6 * (C) Copyright 2005
7 * 2N Telekomunikace, a.s. <www.2n.cz>
8 * Ladislav Michl <michl@2n.cz>
9 *
10 * See file CREDITS for list of people who contributed to this
11 * project.
12 *
13 * This program is free software; you can redistribute it and/or
14 * modify it under the terms of the GNU General Public License as
15 * published by the Free Software Foundation; either version 2 of
16 * the License, or (at your option) any later version.
17 *
18 * This program is distributed in the hope that it will be useful,
19 * but WITHOUT ANY WARRANTY; without even the implied warranty of
20 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
21 * GNU General Public License for more details.
22 *
23 * You should have received a copy of the GNU General Public License
24 * along with this program; if not, write to the Free Software
25 * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
26 * MA 02111-1307 USA
27 */
28
29#include <common.h>
30
31/*#if 0 */
32#if (PHYS_SDRAM_1_SIZE != SZ_32M)
33
34#include "crcek.h"
35
36#if (CFG_MAX_FLASH_BANKS > 1)
37#error There is always only _one_ flash chip
38#endif
39
40flash_info_t flash_info[CFG_MAX_FLASH_BANKS];
41
42#define CMD_READ_ARRAY          0x000000f0
43#define CMD_UNLOCK1             0x000000aa
44#define CMD_UNLOCK2             0x00000055
45#define CMD_ERASE_SETUP         0x00000080
46#define CMD_ERASE_CONFIRM       0x00000030
47#define CMD_PROGRAM             0x000000a0
48#define CMD_UNLOCK_BYPASS       0x00000020
49
50#define MEM_FLASH_ADDR1         (*(volatile u16 *)(CFG_FLASH_BASE + (0x00000555 << 1)))
51#define MEM_FLASH_ADDR2         (*(volatile u16 *)(CFG_FLASH_BASE + (0x000002aa << 1)))
52
53#define BIT_ERASE_DONE          0x00000080
54#define BIT_RDY_MASK            0x00000080
55#define BIT_PROGRAM_ERROR       0x00000020
56#define BIT_TIMEOUT             0x80000000      /* our flag */
57
58/*-----------------------------------------------------------------------
59 */
60
61ulong flash_init(void)
62{
63        int i;
64
65        flash_info[0].flash_id = (AMD_MANUFACT & FLASH_VENDMASK) |
66                                 (AMD_ID_LV800B & FLASH_TYPEMASK);
67        flash_info[0].size = PHYS_FLASH_1_SIZE;
68        flash_info[0].sector_count = CFG_MAX_FLASH_SECT;
69        memset(flash_info[0].protect, 0, CFG_MAX_FLASH_SECT);
70
71        for (i = 0; i < flash_info[0].sector_count; i++) {
72                switch (i) {
73                case 0: /* 16kB */
74                        flash_info[0].start[0] = CFG_FLASH_BASE;
75                        break;
76                case 1: /* 8kB */
77                        flash_info[0].start[1] = CFG_FLASH_BASE + 0x4000;
78                        break;
79                case 2: /* 8kB */
80                        flash_info[0].start[2] = CFG_FLASH_BASE + 0x4000 +
81                                                 0x2000;
82                        break;
83                case 3: /* 32 KB */
84                        flash_info[0].start[3] = CFG_FLASH_BASE + 0x4000 +
85                                                 2 * 0x2000;
86                        break;
87                case 4:
88                        flash_info[0].start[4] = CFG_FLASH_BASE + 0x4000 +
89                                                 2 * 0x2000 + 0x8000;
90                        break;
91                default: /* 64kB */
92                        flash_info[0].start[i] = flash_info[0].start[i-1] +
93                                                 0x10000;
94                        break;
95                }
96        }
97
98        /* U-Boot */
99        flash_protect(FLAG_PROTECT_SET,
100                      LOADER1_OFFSET,
101                      LOADER1_OFFSET + LOADER_SIZE - 1, flash_info);
102        /* Protect crcek, env and r_env as well */
103        flash_protect(FLAG_PROTECT_SET, 0, 0x8000 - 1, flash_info);
104
105        return flash_info[0].size;
106}
107
108/*-----------------------------------------------------------------------
109 */
110void flash_print_info(flash_info_t *info)
111{
112        int i;
113
114        switch (info->flash_id & FLASH_VENDMASK) {
115        case (AMD_MANUFACT & FLASH_VENDMASK):
116                puts("AMD: ");
117                break;
118        default:
119                puts("Unknown vendor ");
120                break;
121        }
122
123        switch (info->flash_id & FLASH_TYPEMASK) {
124        case (AMD_ID_LV800B & FLASH_TYPEMASK):
125                puts("AM29LV800BB (8Mb)\n");
126                break;
127        default:
128                puts("Unknown chip type\n");
129                return;
130        }
131
132        printf("  Size: %ld MB in %d sectors\n",
133               info->size >> 20, info->sector_count);
134
135        puts("  Sector start addresses:");
136        for (i = 0; i < info->sector_count; i++) {
137                if ((i % 5) == 0)
138                        puts("\n   ");
139
140                printf(" %08lX%s", info->start[i],
141                       info->protect[i] ? " (RO)" : "     ");
142        }
143        puts("\n");
144}
145
146/*-----------------------------------------------------------------------
147 */
148
149int flash_erase(flash_info_t *info, int s_first, int s_last)
150{
151        ushort result;
152        int prot, sect;
153        int rc = ERR_OK;
154
155        /* first look for protection bits */
156
157        if (info->flash_id == FLASH_UNKNOWN)
158                return ERR_UNKNOWN_FLASH_TYPE;
159
160        if ((s_first < 0) || (s_first > s_last))
161                return ERR_INVAL;
162
163        if ((info->flash_id & FLASH_VENDMASK) !=
164            (AMD_MANUFACT & FLASH_VENDMASK))
165                return ERR_UNKNOWN_FLASH_VENDOR;
166
167        prot = 0;
168        for (sect = s_first; sect <= s_last; ++sect)
169                if (info->protect[sect])
170                        prot++;
171
172        if (prot)
173                printf("- Warning: %d protected sectors will not be erased!\n",
174                       prot);
175        else
176                putc('\n');
177
178        /* Start erase on unprotected sectors */
179        for (sect = s_first; sect <= s_last && !ctrlc (); sect++) {
180                if (info->protect[sect] == 0) { /* not protected */
181                        vu_short *addr = (vu_short *) (info->start[sect]);
182
183                        /* arm simple, non interrupt dependent timer */
184                        reset_timer_masked();
185
186                        MEM_FLASH_ADDR1 = CMD_UNLOCK1;
187                        MEM_FLASH_ADDR2 = CMD_UNLOCK2;
188                        MEM_FLASH_ADDR1 = CMD_ERASE_SETUP;
189
190                        MEM_FLASH_ADDR1 = CMD_UNLOCK1;
191                        MEM_FLASH_ADDR2 = CMD_UNLOCK2;
192                        *addr = CMD_ERASE_CONFIRM;
193
194                        /* wait until flash is ready */
195                        while (1) {
196                                result = *addr;
197
198                                /* check timeout */
199                                if (get_timer_masked() > CFG_FLASH_ERASE_TOUT) {
200                                        MEM_FLASH_ADDR1 = CMD_READ_ARRAY;
201                                        rc = ERR_TIMOUT;
202                                        break;
203                                }
204
205                                if ((result & 0xfff) & BIT_ERASE_DONE)
206                                        break;
207
208                                if ((result & 0xffff) & BIT_PROGRAM_ERROR) {
209                                        rc = ERR_PROG_ERROR;
210                                        break;
211                                }
212                        }
213
214                        MEM_FLASH_ADDR1 = CMD_READ_ARRAY;
215
216                        if (rc != ERR_OK)
217                                goto out;
218
219                        putc('.');
220                }
221        }
222out:
223        /* allow flash to settle - wait 10 ms */
224        udelay_masked(10000);
225
226        return rc;
227}
228
229/*-----------------------------------------------------------------------
230 * Copy memory to flash
231 */
232
233static int write_hword(flash_info_t *info, ulong dest, ushort data)
234{
235        vu_short *addr = (vu_short *) dest;
236        ushort result;
237        int rc = ERR_OK;
238
239        /* check if flash is (sufficiently) erased */
240        result = *addr;
241        if ((result & data) != data)
242                return ERR_NOT_ERASED;
243
244        MEM_FLASH_ADDR1 = CMD_UNLOCK1;
245        MEM_FLASH_ADDR2 = CMD_UNLOCK2;
246        MEM_FLASH_ADDR1 = CMD_PROGRAM;
247        *addr = data;
248
249        /* arm simple, non interrupt dependent timer */
250        reset_timer_masked();
251
252        /* wait until flash is ready */
253        while (1) {
254                result = *addr;
255
256                /* check timeout */
257                if (get_timer_masked () > CFG_FLASH_ERASE_TOUT) {
258                        rc = ERR_TIMOUT;
259                        break;
260                }
261
262                if ((result & 0x80) == (data & 0x80))
263                        break;
264
265                if ((result & 0xffff) & BIT_PROGRAM_ERROR) {
266                        result = *addr;
267
268                        if ((result & 0x80) != (data & 0x80))
269                                rc = ERR_PROG_ERROR;
270                }
271        }
272
273        *addr = CMD_READ_ARRAY;
274
275        if (*addr != data)
276                rc = ERR_PROG_ERROR;
277
278        return rc;
279}
280
281/*-----------------------------------------------------------------------
282 * Copy memory to flash.
283 */
284
285int write_buff(flash_info_t *info, uchar *src, ulong addr, ulong cnt)
286{
287        ulong cp, wp;
288        int l;
289        int i, rc;
290        ushort data;
291
292        wp = (addr & ~1);       /* get lower word aligned address */
293
294        /*
295         * handle unaligned start bytes
296         */
297        if ((l = addr - wp) != 0) {
298                data = 0;
299                for (i = 0, cp = wp; i < l; ++i, ++cp)
300                        data = (data >> 8) | (*(uchar *) cp << 8);
301                for (; i < 2 && cnt > 0; ++i) {
302                        data = (data >> 8) | (*src++ << 8);
303                        --cnt;
304                        ++cp;
305                }
306                for (; cnt == 0 && i < 2; ++i, ++cp)
307                        data = (data >> 8) | (*(uchar *) cp << 8);
308
309                if ((rc = write_hword(info, wp, data)) != 0)
310                        return (rc);
311                wp += 2;
312        }
313
314        /*
315         * handle word aligned part
316         */
317        while (cnt >= 2) {
318                data = *((vu_short *) src);
319                if ((rc = write_hword(info, wp, data)) != 0)
320                        return (rc);
321                src += 2;
322                wp += 2;
323                cnt -= 2;
324        }
325
326        if (cnt == 0)
327                return ERR_OK;
328
329        /*
330         * handle unaligned tail bytes
331         */
332        data = 0;
333        for (i = 0, cp = wp; i < 2 && cnt > 0; ++i, ++cp) {
334                data = (data >> 8) | (*src++ << 8);
335                --cnt;
336        }
337        for (; i < 2; ++i, ++cp)
338                data = (data >> 8) | (*(uchar *) cp << 8);
339
340        return write_hword(info, wp, data);
341}
342
343#endif
Note: See TracBrowser for help on using the repository browser.