source: SVN/rincon/u-boot/board/BuS/EB+MCF-EV123/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: 8.4 KB
Line 
1/*
2 * (C) Copyright 2005
3 * BuS Elektronik GmbH & Co.KG <esw@bus-elektonik.de>
4 *
5 * Based On
6 * Wolfgang Denk, DENX Software Engineering, wd@denx.de.
7 *
8 * See file CREDITS for list of people who contributed to this
9 * project.
10 *
11 * This program is free software; you can redistribute it and/or
12 * modify it under the terms of the GNU General Public License as
13 * published by the Free Software Foundation; either version 2 of
14 * the License, or (at your option) any later version.
15 *
16 * This program is distributed in the hope that it will be useful,
17 * but WITHOUT ANY WARRANTY; without even the implied warranty of
18 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
19 * GNU General Public License for more details.
20 *
21 * You should have received a copy of the GNU General Public License
22 * along with this program; if not, write to the Free Software
23 * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
24 * MA 02111-1307 USA
25 */
26
27#include <common.h>
28#include  "cfm_flash.h"
29
30#define PHYS_FLASH_1 CFG_FLASH_BASE
31#define FLASH_BANK_SIZE 0x200000
32
33flash_info_t flash_info[CFG_MAX_FLASH_BANKS];
34
35void flash_print_info (flash_info_t * info)
36{
37        int i;
38
39        switch (info->flash_id & FLASH_VENDMASK) {
40        case (AMD_MANUFACT & FLASH_VENDMASK):
41                printf ("AMD: ");
42                switch (info->flash_id & FLASH_TYPEMASK) {
43                case (AMD_ID_LV160B & FLASH_TYPEMASK):
44                        printf ("AM29LV160B (16Bit)\n");
45                        break;
46                default:
47                        printf ("Unknown Chip Type\n");
48                        break;
49                }
50                break;
51        case FREESCALE_MANUFACT & FLASH_VENDMASK:
52                cfm_flash_print_info (info);
53                break;
54        default:
55                printf ("Unknown Vendor ");
56                break;
57        }
58
59        puts ("  Size: ");
60        if ((info->size >> 20) > 0)
61        {
62                printf ("%ld MiB",info->size >> 20);
63        }
64        else
65        {
66                printf ("%ld KiB",info->size >> 10);
67        }
68        printf (" in %d Sectors\n", info->sector_count);
69
70        printf ("  Sector Start Addresses:");
71        for (i = 0; i < info->sector_count; i++) {
72                if ((i % 4) == 0) {
73                        printf ("\n    ");
74                }
75                printf ("%02d: %08lX%s  ", i,info->start[i],
76                        info->protect[i] ? " P" : "  ");
77        }
78        printf ("\n\n");
79}
80
81unsigned long flash_init (void)
82{
83        int i, j;
84        ulong size = 0;
85
86        for (i = 0; i < CFG_MAX_FLASH_BANKS; i++) {
87                ulong flashbase = 0;
88
89                switch (i)
90                {
91                case 1:
92                        flash_info[i].flash_id =
93                                (AMD_MANUFACT & FLASH_VENDMASK) |
94                                (AMD_ID_LV160B & FLASH_TYPEMASK);
95                        flash_info[i].size = FLASH_BANK_SIZE;
96                        flash_info[i].sector_count = CFG_MAX_FLASH_SECT;
97                        memset (flash_info[i].protect, 0, CFG_MAX_FLASH_SECT);
98                        flashbase = PHYS_FLASH_1;
99                        for (j = 0; j < flash_info[i].sector_count; j++) {
100                                if (j == 0) {
101                                        /* 1st is 16 KiB */
102                                        flash_info[i].start[j] = flashbase;
103                                }
104                                if ((j >= 1) && (j <= 2)) {
105                                /* 2nd and 3rd are 8 KiB */
106                                        flash_info[i].start[j] =
107                                                flashbase + 0x4000 + 0x2000 * (j - 1);
108                                }
109                                if (j == 3) {
110                                        /* 4th is 32 KiB */
111                                        flash_info[i].start[j] = flashbase + 0x8000;
112                                }
113                                if ((j >= 4) && (j <= 34)) {
114                                        /* rest is 256 KiB */
115                                        flash_info[i].start[j] =
116                                                flashbase + 0x10000 + 0x10000 * (j - 4);
117                                }
118                        }
119                        break;
120                case 0:
121                        cfm_flash_init (&flash_info[i]);
122                        break;
123                default:
124                        panic ("configured to many flash banks!\n");
125                }
126
127                size += flash_info[i].size;
128        }
129
130        flash_protect (FLAG_PROTECT_SET,
131                       CFG_FLASH_BASE,
132                       CFG_FLASH_BASE + 0xffff, &flash_info[0]);
133
134        return size;
135}
136
137#define CMD_READ_ARRAY          0x00F0
138#define CMD_UNLOCK1             0x00AA
139#define CMD_UNLOCK2             0x0055
140#define CMD_ERASE_SETUP         0x0080
141#define CMD_ERASE_CONFIRM       0x0030
142#define CMD_PROGRAM             0x00A0
143#define CMD_UNLOCK_BYPASS       0x0020
144
145#define MEM_FLASH_ADDR1         (*(volatile u16 *)(info->start[0] + (0x00000555<<1)))
146#define MEM_FLASH_ADDR2         (*(volatile u16 *)(info->start[0] + (0x000002AA<<1)))
147
148
149#define BIT_ERASE_DONE          0x0080
150#define BIT_RDY_MASK            0x0080
151#define BIT_PROGRAM_ERROR       0x0020
152#define BIT_TIMEOUT             0x80000000      /* our flag */
153
154#define ERR_READY -1
155
156int amd_flash_erase_sector(flash_info_t * info, int sector)
157{
158        int state;
159        ulong result;
160
161        volatile u16 *addr =
162                                (volatile u16 *) (info->start[sector]);
163
164        MEM_FLASH_ADDR1 = CMD_UNLOCK1;
165        MEM_FLASH_ADDR2 = CMD_UNLOCK2;
166        MEM_FLASH_ADDR1 = CMD_ERASE_SETUP;
167
168        MEM_FLASH_ADDR1 = CMD_UNLOCK1;
169        MEM_FLASH_ADDR2 = CMD_UNLOCK2;
170        *addr = CMD_ERASE_CONFIRM;
171
172        /* wait until flash is ready */
173        state = 0;
174        set_timer (0);
175
176        do {
177                result = *addr;
178
179                /* check timeout */
180                if (get_timer (0) > CFG_FLASH_ERASE_TOUT) {
181                        MEM_FLASH_ADDR1 = CMD_READ_ARRAY;
182                        state = ERR_TIMOUT;
183                }
184
185                if (!state && (result & 0xFFFF) & BIT_ERASE_DONE)
186                        state = ERR_READY;
187        }
188        while (!state);
189        if (state == ERR_READY)
190                state = ERR_OK;
191
192        MEM_FLASH_ADDR1 = CMD_READ_ARRAY;
193
194        return state;
195}
196
197int flash_erase (flash_info_t * info, int s_first, int s_last)
198{
199        int iflag, cflag;
200        int sector;
201        int rc;
202
203        rc = ERR_OK;
204
205        if (info->flash_id == FLASH_UNKNOWN)
206        {
207                rc = ERR_UNKNOWN_FLASH_TYPE;
208        } /* (info->flash_id == FLASH_UNKNOWN) */
209
210        if ((s_first < 0) || (s_first > s_last) || s_last >= info->sector_count)
211        {
212                rc = ERR_INVAL;
213        }
214
215        cflag = icache_status ();
216        icache_disable ();
217        iflag = disable_interrupts ();
218
219        for (sector = s_first; (sector <= s_last) && (rc == ERR_OK); sector++) {
220
221                if (info->protect[sector])
222                {
223                        putc('P'); /*  protected sector will not erase */
224                }
225                else
226                {
227                        /* erase on unprotected sector */
228                        puts("E\b");
229                        switch (info->flash_id & FLASH_VENDMASK)
230                        {
231                        case (AMD_MANUFACT & FLASH_VENDMASK):
232                                rc = amd_flash_erase_sector(info,sector);
233                                break;
234                        case (FREESCALE_MANUFACT & FLASH_VENDMASK):
235                                rc = cfm_flash_erase_sector(info,sector);
236                                break;
237                        default:
238                                return ERR_UNKNOWN_FLASH_VENDOR;
239                        }
240                        putc('.');
241                }
242        }
243        if (rc!=ERR_OK)
244        {
245                printf ("\n   ");
246                flash_perror (rc);
247        }
248        else
249        {
250                printf (" done\n");
251        }
252
253        udelay (10000); /* allow flash to settle - wait 10 ms */
254
255        if (iflag)
256                enable_interrupts ();
257
258        if (cflag)
259                icache_enable ();
260
261        return rc;
262}
263
264volatile static int amd_write_word (flash_info_t * info, ulong dest, u16 data)
265{
266        volatile u16 *addr;
267        ulong result;
268        int cflag, iflag;
269        int state;
270
271        /*
272         * Check if Flash is (sufficiently) erased
273         */
274        addr = (volatile u16 *) dest;
275
276        result = *addr;
277        if ((result & data) != data)
278                return ERR_NOT_ERASED;
279
280        /*
281         * Disable interrupts which might cause a timeout
282         * here. Remember that our exception vectors are
283         * at address 0 in the flash, and we don't want a
284         * (ticker) exception to happen while the flash
285         * chip is in programming mode.
286         */
287
288        cflag = icache_status ();
289        icache_disable ();
290        iflag = disable_interrupts ();
291
292        MEM_FLASH_ADDR1 = CMD_UNLOCK1;
293        MEM_FLASH_ADDR2 = CMD_UNLOCK2;
294        MEM_FLASH_ADDR1 = CMD_PROGRAM;
295        *addr = data;
296
297        /* arm simple, non interrupt dependent timer */
298        set_timer (0);
299
300        /* wait until flash is ready */
301        state = 0;
302        do {
303                result = *addr;
304
305                /* check timeout */
306                if (get_timer (0) > CFG_FLASH_ERASE_TOUT) {
307                                state = ERR_TIMOUT;
308                }
309                if (!state && ((result & BIT_RDY_MASK) == (data & BIT_RDY_MASK)))
310                        state = ERR_READY;
311
312        } while (!state);
313
314        *addr = CMD_READ_ARRAY;
315
316        if (state == ERR_READY)
317                state = ERR_OK;
318        if ((*addr != data) && (state != ERR_TIMOUT))
319                state = ERR_PROG_ERROR;
320
321        if (iflag)
322                enable_interrupts ();
323
324        if (cflag)
325                icache_enable ();
326
327        return state;
328}
329
330int amd_flash_write_buff(flash_info_t * info, uchar * src, ulong addr, ulong cnt)
331{
332        int rc;
333        ulong dest;
334        u16 data;
335
336        rc = ERR_OK;
337        if (addr & 1)
338        {
339                debug ("Byte alignment not supported\n");
340                rc = ERR_ALIGN;
341        }
342        if (cnt & 1)
343        {
344                debug ("Byte transfer not supported\n");
345                rc = ERR_ALIGN;
346        }
347
348        dest = addr;
349        while ((cnt>=2) && (rc == ERR_OK))
350        {
351                data = *((volatile u16 *) src);
352                rc=amd_write_word (info,dest,data);
353                src +=2;
354                dest +=2;
355                cnt -=2;
356        }
357        return rc;
358}
359
360int write_buff (flash_info_t * info, uchar * src, ulong addr, ulong cnt)
361{
362        int rc;
363
364        switch (info->flash_id & FLASH_VENDMASK)
365        {
366                case (AMD_MANUFACT & FLASH_VENDMASK):
367                        rc = amd_flash_write_buff(info,src,addr,cnt);
368                        break;
369                case (FREESCALE_MANUFACT & FLASH_VENDMASK):
370                        rc = cfm_flash_write_buff(info,src,addr,cnt);
371                        break;
372                default:
373                        rc = ERR_UNKNOWN_FLASH_VENDOR;
374        }
375        return rc;
376
377}
378int amd_flash_protect(flash_info_t * info,long sector,int prot)
379{
380        int rc;
381        rc= ERR_OK;
382        if (prot)
383        {
384                info->protect[sector]=1;
385        }
386        else
387        {
388                info->protect[sector]=0;
389        }
390        return rc;
391}
392
393#ifdef CFG_FLASH_PROTECTION
394
395int flash_real_protect(flash_info_t * info,long sector,int prot)
396{
397        int rc;
398
399        switch (info->flash_id & FLASH_VENDMASK)
400        {
401                case (AMD_MANUFACT & FLASH_VENDMASK):
402                        rc = amd_flash_protect(info,sector,prot);
403                        break;
404                case (FREESCALE_MANUFACT & FLASH_VENDMASK):
405                        rc = cfm_flash_protect(info,sector,prot);
406                        break;
407                default:
408                        rc = ERR_UNKNOWN_FLASH_VENDOR;
409        }
410        return rc;
411}
412
413#endif
Note: See TracBrowser for help on using the repository browser.