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

« back to all changes in this revision

Viewing changes to board/sc520_cdp/flash_old.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
 * Daniel Engstrļæ½m, Omicron Ceti AB, daniel@omicron.se
 
4
 *
 
5
 * (C) Copyright 2002
 
6
 * Sysgo Real-Time Solutions, GmbH <www.elinos.com>
 
7
 * Alex Zuepke <azu@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
#include <asm/io.h>
 
30
 
 
31
ulong myflush(void);
 
32
 
 
33
 
 
34
#define SC520_MAX_FLASH_BANKS  3
 
35
#define SC520_FLASH_BANK0_BASE 0x38000000  /* BOOTCS */
 
36
#define SC520_FLASH_BANK1_BASE 0x30000000  /* ROMCS0 */
 
37
#define SC520_FLASH_BANK2_BASE 0x28000000  /* ROMCS1 */
 
38
#define SC520_FLASH_BANKSIZE   0x8000000
 
39
 
 
40
#define AMD29LV016_SIZE        0x200000
 
41
#define AMD29LV016_SECTORS     32
 
42
 
 
43
flash_info_t    flash_info[SC520_MAX_FLASH_BANKS];
 
44
 
 
45
#define CMD_READ_ARRAY          0x00F000F0
 
46
#define CMD_UNLOCK1             0x00AA00AA
 
47
#define CMD_UNLOCK2             0x00550055
 
48
#define CMD_ERASE_SETUP         0x00800080
 
49
#define CMD_ERASE_CONFIRM       0x00300030
 
50
#define CMD_PROGRAM             0x00A000A0
 
51
#define CMD_UNLOCK_BYPASS       0x00200020
 
52
 
 
53
 
 
54
#define BIT_ERASE_DONE          0x00800080
 
55
#define BIT_RDY_MASK            0x00800080
 
56
#define BIT_PROGRAM_ERROR       0x00200020
 
57
#define BIT_TIMEOUT             0x80000000 /* our flag */
 
58
 
 
59
#define READY 1
 
60
#define ERR   2
 
61
#define TMO   4
 
62
 
 
63
/*-----------------------------------------------------------------------
 
64
 */
 
65
 
 
66
ulong flash_init(void)
 
67
{
 
68
        int i, j;
 
69
        ulong size = 0;
 
70
 
 
71
        for (i = 0; i < SC520_MAX_FLASH_BANKS; i++) {
 
72
                ulong flashbase = 0;
 
73
                int sectsize = 0;
 
74
                if (i==0 || i==2) {
 
75
                        /* FixMe: this assumes that bank 0 and 2
 
76
                         * are mapped to the two 8Mb banks */
 
77
                        flash_info[i].flash_id =
 
78
                                (AMD_MANUFACT & FLASH_VENDMASK) |
 
79
                                (AMD_ID_LV016B & FLASH_TYPEMASK);
 
80
 
 
81
                        flash_info[i].size = AMD29LV016_SIZE*4;
 
82
                        flash_info[i].sector_count = AMD29LV016_SECTORS;
 
83
                        sectsize = (AMD29LV016_SIZE*4)/AMD29LV016_SECTORS;
 
84
                } else {
 
85
                        /* FixMe: this assumes that bank1 is unmapped
 
86
                         * (or mapped to the same flash bank as BOOTCS) */
 
87
                        flash_info[i].flash_id = 0;
 
88
                        flash_info[i].size = 0;
 
89
                        flash_info[i].sector_count = 0;
 
90
                        sectsize=0;
 
91
                }
 
92
                memset(flash_info[i].protect, 0, CONFIG_SYS_MAX_FLASH_SECT);
 
93
                switch (i) {
 
94
                case 0:
 
95
                        flashbase = SC520_FLASH_BANK0_BASE;
 
96
                        break;
 
97
                case 1:
 
98
                        flashbase = SC520_FLASH_BANK1_BASE;
 
99
                        break;
 
100
                case 2:
 
101
                        flashbase = SC520_FLASH_BANK0_BASE;
 
102
                        break;
 
103
                default:
 
104
                        panic("configured too many flash banks!\n");
 
105
                }
 
106
 
 
107
                for (j = 0; j < flash_info[i].sector_count; j++) {
 
108
                        flash_info[i].start[j] = sectsize;
 
109
                        flash_info[i].start[j] = flashbase + j * sectsize;
 
110
                }
 
111
                size += flash_info[i].size;
 
112
        }
 
113
 
 
114
        /*
 
115
         * Protect monitor and environment sectors
 
116
         */
 
117
        flash_protect(FLAG_PROTECT_SET,
 
118
                      i386boot_start-SC520_FLASH_BANK0_BASE,
 
119
                      i386boot_end-SC520_FLASH_BANK0_BASE,
 
120
                      &flash_info[0]);
 
121
 
 
122
#ifdef CONFIG_ENV_ADDR
 
123
        flash_protect(FLAG_PROTECT_SET,
 
124
                      CONFIG_ENV_ADDR,
 
125
                      CONFIG_ENV_ADDR + CONFIG_ENV_SIZE - 1,
 
126
                      &flash_info[0]);
 
127
#endif
 
128
        return size;
 
129
}
 
130
 
 
131
/*-----------------------------------------------------------------------
 
132
 */
 
133
void flash_print_info(flash_info_t *info)
 
134
{
 
135
        int i;
 
136
 
 
137
        switch (info->flash_id & FLASH_VENDMASK) {
 
138
        case (AMD_MANUFACT & FLASH_VENDMASK):
 
139
                printf("AMD: ");
 
140
                break;
 
141
        default:
 
142
                printf("Unknown Vendor ");
 
143
                break;
 
144
        }
 
145
 
 
146
        switch (info->flash_id & FLASH_TYPEMASK) {
 
147
        case (AMD_ID_LV016B & FLASH_TYPEMASK):
 
148
                printf("4x Amd29LV016B (16Mbit)\n");
 
149
                break;
 
150
        default:
 
151
                printf("Unknown Chip Type\n");
 
152
                goto done;
 
153
                break;
 
154
        }
 
155
 
 
156
        printf("  Size: %ld MB in %d Sectors\n",
 
157
               info->size >> 20, info->sector_count);
 
158
 
 
159
        printf("  Sector Start Addresses:");
 
160
        for (i = 0; i < info->sector_count; i++) {
 
161
                if ((i % 5) == 0) {
 
162
                        printf ("\n   ");
 
163
                }
 
164
                printf (" %08lX%s", info->start[i],
 
165
                        info->protect[i] ? " (RO)" : "     ");
 
166
        }
 
167
        printf ("\n");
 
168
 
 
169
        done:
 
170
}
 
171
 
 
172
/*-----------------------------------------------------------------------
 
173
 */
 
174
 
 
175
int flash_erase(flash_info_t *info, int s_first, int s_last)
 
176
{
 
177
        ulong result;
 
178
        int iflag, prot, sect;
 
179
        int rc = ERR_OK;
 
180
        int chip1, chip2;
 
181
 
 
182
        /* first look for protection bits */
 
183
 
 
184
        if (info->flash_id == FLASH_UNKNOWN) {
 
185
                return ERR_UNKNOWN_FLASH_TYPE;
 
186
        }
 
187
 
 
188
        if ((s_first < 0) || (s_first > s_last)) {
 
189
                return ERR_INVAL;
 
190
        }
 
191
 
 
192
        if ((info->flash_id & FLASH_VENDMASK) !=
 
193
            (AMD_MANUFACT & FLASH_VENDMASK)) {
 
194
                return ERR_UNKNOWN_FLASH_VENDOR;
 
195
        }
 
196
 
 
197
        prot = 0;
 
198
        for (sect=s_first; sect<=s_last; ++sect) {
 
199
                if (info->protect[sect]) {
 
200
                        prot++;
 
201
                }
 
202
        }
 
203
        if (prot) {
 
204
                return ERR_PROTECTED;
 
205
        }
 
206
 
 
207
        /*
 
208
         * Disable interrupts which might cause a timeout
 
209
         * here. Remember that our exception vectors are
 
210
         * at address 0 in the flash, and we don't want a
 
211
         * (ticker) exception to happen while the flash
 
212
         * chip is in programming mode.
 
213
         */
 
214
        iflag = disable_interrupts();
 
215
 
 
216
        /* Start erase on unprotected sectors */
 
217
        for (sect = s_first; sect<=s_last && !ctrlc(); sect++) {
 
218
                printf("Erasing sector %2d ... ", sect);
 
219
 
 
220
                /* arm simple, non interrupt dependent timer */
 
221
                reset_timer();
 
222
 
 
223
                if (info->protect[sect] == 0) {
 
224
                        /* not protected */
 
225
                        ulong addr = info->start[sect];
 
226
 
 
227
                        writel(CMD_UNLOCK1, addr + 1);
 
228
                        writel(CMD_UNLOCK2, addr + 2);
 
229
                        writel(CMD_ERASE_SETUP, addr + 1);
 
230
 
 
231
                        writel(CMD_UNLOCK1, addr + 1);
 
232
                        writel(CMD_UNLOCK2, addr + 2);
 
233
                        writel(CMD_ERASE_CONFIRM, addr);
 
234
 
 
235
 
 
236
                        /* wait until flash is ready */
 
237
                        chip1 = chip2 = 0;
 
238
 
 
239
                        do {
 
240
                                result = readl(addr);
 
241
 
 
242
                                /* check timeout */
 
243
                                if (get_timer(0) > CONFIG_SYS_FLASH_ERASE_TOUT) {
 
244
                                        writel(CMD_READ_ARRAY, addr + 1);
 
245
                                        chip1 = TMO;
 
246
                                        break;
 
247
                                }
 
248
 
 
249
                                if (!chip1 && (result & 0xFFFF) & BIT_ERASE_DONE) {
 
250
                                        chip1 = READY;
 
251
                                }
 
252
 
 
253
                                if (!chip1 && (result & 0xFFFF) & BIT_PROGRAM_ERROR) {
 
254
                                        chip1 = ERR;
 
255
                                }
 
256
 
 
257
                                if (!chip2 && (result >> 16) & BIT_ERASE_DONE) {
 
258
                                        chip2 = READY;
 
259
                                }
 
260
 
 
261
                                if (!chip2 && (result >> 16) & BIT_PROGRAM_ERROR) {
 
262
                                        chip2 = ERR;
 
263
                                }
 
264
 
 
265
                        }  while (!chip1 || !chip2);
 
266
 
 
267
                        writel(CMD_READ_ARRAY, addr + 1);
 
268
 
 
269
                        if (chip1 == ERR || chip2 == ERR) {
 
270
                                rc = ERR_PROG_ERROR;
 
271
                                goto outahere;
 
272
                        }
 
273
 
 
274
                        if (chip1 == TMO) {
 
275
                                rc = ERR_TIMOUT;
 
276
                                goto outahere;
 
277
                        }
 
278
 
 
279
                        printf("ok.\n");
 
280
                } else { /* it was protected */
 
281
 
 
282
                        printf("protected!\n");
 
283
                }
 
284
        }
 
285
 
 
286
        if (ctrlc()) {
 
287
                printf("User Interrupt!\n");
 
288
        }
 
289
 
 
290
outahere:
 
291
        /* allow flash to settle - wait 10 ms */
 
292
        udelay(10000);
 
293
 
 
294
        if (iflag) {
 
295
                enable_interrupts();
 
296
        }
 
297
 
 
298
        return rc;
 
299
}
 
300
 
 
301
/*-----------------------------------------------------------------------
 
302
 * Copy memory to flash
 
303
 */
 
304
 
 
305
volatile static int write_word(flash_info_t *info, ulong dest, ulong data)
 
306
{
 
307
        ulong addr = dest;
 
308
        ulong result;
 
309
        int rc = ERR_OK;
 
310
        int iflag;
 
311
        int chip1, chip2;
 
312
 
 
313
        /*
 
314
         * Check if Flash is (sufficiently) erased
 
315
         */
 
316
        result = readl(addr);
 
317
        if ((result & data) != data) {
 
318
                return ERR_NOT_ERASED;
 
319
        }
 
320
 
 
321
        /*
 
322
         * Disable interrupts which might cause a timeout
 
323
         * here. Remember that our exception vectors are
 
324
         * at address 0 in the flash, and we don't want a
 
325
         * (ticker) exception to happen while the flash
 
326
         * chip is in programming mode.
 
327
         */
 
328
        iflag = disable_interrupts();
 
329
 
 
330
        writel(CMD_UNLOCK1, addr + 1);
 
331
        writel(CMD_UNLOCK2, addr + 2);
 
332
        writel(CMD_UNLOCK_BYPASS, addr + 1);
 
333
        writel(addr, CMD_PROGRAM);
 
334
        writel(addr, data);
 
335
 
 
336
        /* arm simple, non interrupt dependent timer */
 
337
        reset_timer();
 
338
 
 
339
        /* wait until flash is ready */
 
340
        chip1 = chip2 = 0;
 
341
        do {
 
342
                result = readl(addr);
 
343
 
 
344
                /* check timeout */
 
345
                if (get_timer(0) > CONFIG_SYS_FLASH_ERASE_TOUT) {
 
346
                        chip1 = ERR | TMO;
 
347
                        break;
 
348
                }
 
349
 
 
350
                if (!chip1 && ((result & 0x80) == (data & 0x80))) {
 
351
                        chip1 = READY;
 
352
                }
 
353
 
 
354
                if (!chip1 && ((result & 0xFFFF) & BIT_PROGRAM_ERROR)) {
 
355
                        result = readl(addr);
 
356
 
 
357
                        if ((result & 0x80) == (data & 0x80)) {
 
358
                                chip1 = READY;
 
359
                        } else {
 
360
                                chip1 = ERR;
 
361
                        }
 
362
                }
 
363
 
 
364
                if (!chip2 && ((result & (0x80 << 16)) == (data & (0x80 << 16)))) {
 
365
                        chip2 = READY;
 
366
                }
 
367
 
 
368
                if (!chip2 && ((result >> 16) & BIT_PROGRAM_ERROR)) {
 
369
                        result = readl(addr);
 
370
 
 
371
                        if ((result & (0x80 << 16)) == (data & (0x80 << 16))) {
 
372
                                chip2 = READY;
 
373
                        } else {
 
374
                                chip2 = ERR;
 
375
                        }
 
376
                }
 
377
 
 
378
        }  while (!chip1 || !chip2);
 
379
 
 
380
        writel(CMD_READ_ARRAY, addr);
 
381
 
 
382
        if (chip1 == ERR || chip2 == ERR || readl(addr) != data) {
 
383
                rc = ERR_PROG_ERROR;
 
384
        }
 
385
 
 
386
        if (iflag) {
 
387
                enable_interrupts();
 
388
        }
 
389
 
 
390
        return rc;
 
391
}
 
392
 
 
393
/*-----------------------------------------------------------------------
 
394
 * Copy memory to flash.
 
395
 */
 
396
 
 
397
int write_buff(flash_info_t *info, uchar *src, ulong addr, ulong cnt)
 
398
{
 
399
        ulong cp, wp, data;
 
400
        int l;
 
401
        int i, rc;
 
402
 
 
403
        wp = (addr & ~3);       /* get lower word aligned address */
 
404
 
 
405
        /*
 
406
         * handle unaligned start bytes
 
407
         */
 
408
        if ((l = addr - wp) != 0) {
 
409
                data = 0;
 
410
                for (i=0, cp=wp; i<l; ++i, ++cp) {
 
411
                        data = (data >> 8) | (*(uchar *)cp << 24);
 
412
                }
 
413
                for (; i<4 && cnt>0; ++i) {
 
414
                        data = (data >> 8) | (*src++ << 24);
 
415
                        --cnt;
 
416
                        ++cp;
 
417
                }
 
418
                for (; cnt==0 && i<4; ++i, ++cp) {
 
419
                        data = (data >> 8) | (*(uchar *)cp << 24);
 
420
                }
 
421
 
 
422
                if ((rc = write_word(info, wp, data)) != 0) {
 
423
                        return rc;
 
424
                }
 
425
                wp += 4;
 
426
        }
 
427
 
 
428
        /*
 
429
         * handle word aligned part
 
430
         */
 
431
        while (cnt >= 4) {
 
432
                data = *((vu_long*)src);
 
433
                if ((rc = write_word(info, wp, data)) != 0) {
 
434
                        return rc;
 
435
                }
 
436
                src += 4;
 
437
                wp  += 4;
 
438
                cnt -= 4;
 
439
        }
 
440
 
 
441
        if (cnt == 0) {
 
442
                return ERR_OK;
 
443
        }
 
444
 
 
445
        /*
 
446
         * handle unaligned tail bytes
 
447
         */
 
448
        data = 0;
 
449
        for (i=0, cp=wp; i<4 && cnt>0; ++i, ++cp) {
 
450
                data = (data >> 8) | (*src++ << 24);
 
451
                --cnt;
 
452
        }
 
453
        for (; i<4; ++i, ++cp) {
 
454
                data = (data >> 8) | (*(uchar *)cp << 24);
 
455
        }
 
456
 
 
457
        return write_word(info, wp, data);
 
458
}