~ubuntu-branches/ubuntu/maverick/u-boot-omap3/maverick

« back to all changes in this revision

Viewing changes to board/cradle/flash.c

  • Committer: Bazaar Package Importer
  • Author(s): Oliver Grawert
  • Date: 2010-03-22 15:06:23 UTC
  • Revision ID: james.westby@ubuntu.com-20100322150623-i21g8rgiyl5dohag
Tags: upstream-2010.3git20100315
ImportĀ upstreamĀ versionĀ 2010.3git20100315

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
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
 
 
33
flash_info_t flash_info[CONFIG_SYS_MAX_FLASH_BANKS];
 
34
 
 
35
 
 
36
/*-----------------------------------------------------------------------
 
37
 */
 
38
 
 
39
ulong flash_init (void)
 
40
{
 
41
        int i, j;
 
42
        ulong size = 0;
 
43
 
 
44
        for (i = 0; i < CONFIG_SYS_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 = CONFIG_SYS_MAX_FLASH_SECT;
 
52
                memset (flash_info[i].protect, 0, CONFIG_SYS_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
                       CONFIG_SYS_FLASH_BASE,
 
75
                       CONFIG_SYS_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
 */
 
87
void flash_print_info (flash_info_t * info)
 
88
{
 
89
        int i, j;
 
90
 
 
91
        for (j = 0; j < CONFIG_SYS_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
 
 
129
Done:   ;
 
130
}
 
131
 
 
132
/*-----------------------------------------------------------------------
 
133
 */
 
134
 
 
135
int 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
                                    CONFIG_SYS_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
 
 
204
outahere:
 
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
 
 
219
static 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 () > CONFIG_SYS_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
 
 
283
outahere:
 
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
 
 
297
int 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
}