source: SVN/rincon/u-boot/board/cradle/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.8 KB
Line 
1/*
2 * (C) Copyright 2002
3 * Kyle Harris, Nexus Technologies, Inc. kharris@nexus-tech.net
4 *
5 * (C) Copyright 2002
6 * Sysgo Real-Time Solutions, GmbH <www.elinos.com>
7 * Marius Groeger <mgroeger@sysgo.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#include <common.h>
29
30#define FLASH_BANK_SIZE 0x400000
31#define MAIN_SECT_SIZE  0x20000
32
33flash_info_t flash_info[CFG_MAX_FLASH_BANKS];
34
35
36/*-----------------------------------------------------------------------
37 */
38
39ulong flash_init (void)
40{
41        int i, j;
42        ulong size = 0;
43
44        for (i = 0; i < CFG_MAX_FLASH_BANKS; i++) {
45                ulong flashbase = 0;
46
47                flash_info[i].flash_id =
48                        (INTEL_MANUFACT & FLASH_VENDMASK) |
49                        (INTEL_ID_28F128J3 & FLASH_TYPEMASK);
50                flash_info[i].size = FLASH_BANK_SIZE;
51                flash_info[i].sector_count = CFG_MAX_FLASH_SECT;
52                memset (flash_info[i].protect, 0, CFG_MAX_FLASH_SECT);
53                switch (i) {
54                case 0:
55                        flashbase = PHYS_FLASH_1;
56                        break;
57                case 1:
58                        flashbase = PHYS_FLASH_2;
59                        break;
60                default:
61                        panic ("configured too many flash banks!\n");
62                        break;
63                }
64                for (j = 0; j < flash_info[i].sector_count; j++) {
65                        flash_info[i].start[j] =
66                                flashbase + j * MAIN_SECT_SIZE;
67                }
68                size += flash_info[i].size;
69        }
70
71        /* Protect monitor and environment sectors
72         */
73        flash_protect (FLAG_PROTECT_SET,
74                       CFG_FLASH_BASE,
75                       CFG_FLASH_BASE + monitor_flash_len - 1,
76                       &flash_info[0]);
77
78        flash_protect (FLAG_PROTECT_SET,
79                       CONFIG_ENV_ADDR,
80                       CONFIG_ENV_ADDR + CONFIG_ENV_SIZE - 1, &flash_info[0]);
81
82        return size;
83}
84
85/*-----------------------------------------------------------------------
86 */
87void flash_print_info (flash_info_t * info)
88{
89        int i, j;
90
91        for (j = 0; j < CFG_MAX_FLASH_BANKS; j++) {
92                switch (info->flash_id & FLASH_VENDMASK) {
93                case (INTEL_MANUFACT & FLASH_VENDMASK):
94                        printf ("Intel: ");
95                        break;
96                default:
97                        printf ("Unknown Vendor ");
98                        break;
99                }
100
101                switch (info->flash_id & FLASH_TYPEMASK) {
102                case (INTEL_ID_28F320J3A & FLASH_TYPEMASK):
103                        printf ("28F320J3A (32Mbit)\n");
104                        break;
105                case (INTEL_ID_28F128J3 & FLASH_TYPEMASK):
106                        printf ("28F128J3 (128Mbit)\n");
107                        break;
108                default:
109                        printf ("Unknown Chip Type\n");
110                        goto Done;
111                        break;
112                }
113
114                printf ("  Size: %ld MB in %d Sectors\n",
115                        info->size >> 20, info->sector_count);
116
117                printf ("  Sector Start Addresses:");
118                for (i = 0; i < info->sector_count; i++) {
119                        if ((i % 5) == 0) {
120                                printf ("\n   ");
121                        }
122                        printf (" %08lX%s", info->start[i],
123                                info->protect[i] ? " (RO)" : "     ");
124                }
125                printf ("\n");
126                info++;
127        }
128
129Done:   ;
130}
131
132/*-----------------------------------------------------------------------
133 */
134
135int flash_erase (flash_info_t * info, int s_first, int s_last)
136{
137        int flag, prot, sect;
138        int rc = ERR_OK;
139
140        if (info->flash_id == FLASH_UNKNOWN)
141                return ERR_UNKNOWN_FLASH_TYPE;
142
143        if ((s_first < 0) || (s_first > s_last)) {
144                return ERR_INVAL;
145        }
146
147        if ((info->flash_id & FLASH_VENDMASK) !=
148            (INTEL_MANUFACT & FLASH_VENDMASK)) {
149                return ERR_UNKNOWN_FLASH_VENDOR;
150        }
151
152        prot = 0;
153        for (sect = s_first; sect <= s_last; ++sect) {
154                if (info->protect[sect]) {
155                        prot++;
156                }
157        }
158        if (prot)
159                return ERR_PROTECTED;
160
161        /*
162         * Disable interrupts which might cause a timeout
163         * here. Remember that our exception vectors are
164         * at address 0 in the flash, and we don't want a
165         * (ticker) exception to happen while the flash
166         * chip is in programming mode.
167         */
168        flag = disable_interrupts ();
169
170        /* Start erase on unprotected sectors */
171        for (sect = s_first; sect <= s_last && !ctrlc (); sect++) {
172
173                printf ("Erasing sector %2d ... ", sect);
174
175                /* arm simple, non interrupt dependent timer */
176                reset_timer_masked ();
177
178                if (info->protect[sect] == 0) { /* not protected */
179                        vu_short *addr = (vu_short *) (info->start[sect]);
180
181                        *addr = 0x20;   /* erase setup */
182                        *addr = 0xD0;   /* erase confirm */
183
184                        while ((*addr & 0x80) != 0x80) {
185                                if (get_timer_masked () >
186                                    CFG_FLASH_ERASE_TOUT) {
187                                        *addr = 0xB0;   /* suspend erase */
188                                        *addr = 0xFF;   /* reset to read mode */
189                                        rc = ERR_TIMOUT;
190                                        goto outahere;
191                                }
192                        }
193
194                        /* clear status register command */
195                        *addr = 0x50;
196                        /* reset to read mode */
197                        *addr = 0xFF;
198                }
199                printf ("ok.\n");
200        }
201        if (ctrlc ())
202                printf ("User Interrupt!\n");
203
204outahere:
205
206        /* allow flash to settle - wait 10 ms */
207        udelay_masked (10000);
208
209        if (flag)
210                enable_interrupts ();
211
212        return rc;
213}
214
215/*-----------------------------------------------------------------------
216 * Copy memory to flash
217 */
218
219static int write_word (flash_info_t * info, ulong dest, ushort data)
220{
221        vu_short *addr = (vu_short *) dest, val;
222        int rc = ERR_OK;
223        int flag;
224
225        /* Check if Flash is (sufficiently) erased
226         */
227        if ((*addr & data) != data)
228                return ERR_NOT_ERASED;
229
230        /*
231         * Disable interrupts which might cause a timeout
232         * here. Remember that our exception vectors are
233         * at address 0 in the flash, and we don't want a
234         * (ticker) exception to happen while the flash
235         * chip is in programming mode.
236         */
237        flag = disable_interrupts ();
238
239        /* clear status register command */
240        *addr = 0x50;
241
242        /* program set-up command */
243        *addr = 0x40;
244
245        /* latch address/data */
246        *addr = data;
247
248        /* arm simple, non interrupt dependent timer */
249        reset_timer_masked ();
250
251        /* wait while polling the status register */
252        while (((val = *addr) & 0x80) != 0x80) {
253                if (get_timer_masked () > CFG_FLASH_WRITE_TOUT) {
254                        rc = ERR_TIMOUT;
255                        /* suspend program command */
256                        *addr = 0xB0;
257                        goto outahere;
258                }
259        }
260
261        if (val & 0x1A) {       /* check for error */
262                printf ("\nFlash write error %02x at address %08lx\n",
263                        (int) val, (unsigned long) dest);
264                if (val & (1 << 3)) {
265                        printf ("Voltage range error.\n");
266                        rc = ERR_PROG_ERROR;
267                        goto outahere;
268                }
269                if (val & (1 << 1)) {
270                        printf ("Device protect error.\n");
271                        rc = ERR_PROTECTED;
272                        goto outahere;
273                }
274                if (val & (1 << 4)) {
275                        printf ("Programming error.\n");
276                        rc = ERR_PROG_ERROR;
277                        goto outahere;
278                }
279                rc = ERR_PROG_ERROR;
280                goto outahere;
281        }
282
283outahere:
284        /* read array command */
285        *addr = 0xFF;
286
287        if (flag)
288                enable_interrupts ();
289
290        return rc;
291}
292
293/*-----------------------------------------------------------------------
294 * Copy memory to flash.
295 */
296
297int write_buff (flash_info_t * info, uchar * src, ulong addr, ulong cnt)
298{
299        ulong cp, wp;
300        ushort data;
301        int l;
302        int i, rc;
303
304        wp = (addr & ~1);       /* get lower word aligned address */
305
306        /*
307         * handle unaligned start bytes
308         */
309        if ((l = addr - wp) != 0) {
310                data = 0;
311                for (i = 0, cp = wp; i < l; ++i, ++cp) {
312                        data = (data >> 8) | (*(uchar *) cp << 8);
313                }
314                for (; i < 2 && cnt > 0; ++i) {
315                        data = (data >> 8) | (*src++ << 8);
316                        --cnt;
317                        ++cp;
318                }
319                for (; cnt == 0 && i < 2; ++i, ++cp) {
320                        data = (data >> 8) | (*(uchar *) cp << 8);
321                }
322
323                if ((rc = write_word (info, wp, data)) != 0) {
324                        return (rc);
325                }
326                wp += 2;
327        }
328
329        /*
330         * handle word aligned part
331         */
332        while (cnt >= 2) {
333                data = *((vu_short *) src);
334                if ((rc = write_word (info, wp, data)) != 0) {
335                        return (rc);
336                }
337                src += 2;
338                wp += 2;
339                cnt -= 2;
340        }
341
342        if (cnt == 0) {
343                return ERR_OK;
344        }
345
346        /*
347         * handle unaligned tail bytes
348         */
349        data = 0;
350        for (i = 0, cp = wp; i < 2 && cnt > 0; ++i, ++cp) {
351                data = (data >> 8) | (*src++ << 8);
352                --cnt;
353        }
354        for (; i < 2; ++i, ++cp) {
355                data = (data >> 8) | (*(uchar *) cp << 8);
356        }
357
358        return write_word (info, wp, data);
359}
Note: See TracBrowser for help on using the repository browser.