]> git.kernelconcepts.de Git - karo-tx-uboot.git/blob - board/BuS/EB+MCF-EV123/flash.c
imported Freescale specific U-Boot additions for i.MX28,... release L2.6.31_10.08.01
[karo-tx-uboot.git] / board / BuS / EB+MCF-EV123 / flash.c
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 CONFIG_SYS_FLASH_BASE
31 #define FLASH_BANK_SIZE 0x200000
32
33 flash_info_t flash_info[CONFIG_SYS_MAX_FLASH_BANKS];
34
35 void 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
81 unsigned long flash_init (void)
82 {
83         int i, j;
84         ulong size = 0;
85
86         for (i = 0; i < CONFIG_SYS_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 = CONFIG_SYS_MAX_FLASH_SECT;
97                         memset (flash_info[i].protect, 0, CONFIG_SYS_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                        CONFIG_SYS_FLASH_BASE,
132                        CONFIG_SYS_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
156 int 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) > CONFIG_SYS_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
197 int 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
264 volatile 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) > CONFIG_SYS_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
330 int 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
360 int 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 }
378 int 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 CONFIG_SYS_FLASH_PROTECTION
394
395 int 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