]> git.kernelconcepts.de Git - karo-tx-uboot.git/blob - board/BuS/eb_cpu5282/flash.c
spi: atmel: sam9m10g45 also support WDRBT bit
[karo-tx-uboot.git] / board / BuS / eb_cpu5282 / 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         ulong start;
161
162         volatile u16 *addr =
163                                 (volatile u16 *) (info->start[sector]);
164
165         MEM_FLASH_ADDR1 = CMD_UNLOCK1;
166         MEM_FLASH_ADDR2 = CMD_UNLOCK2;
167         MEM_FLASH_ADDR1 = CMD_ERASE_SETUP;
168
169         MEM_FLASH_ADDR1 = CMD_UNLOCK1;
170         MEM_FLASH_ADDR2 = CMD_UNLOCK2;
171         *addr = CMD_ERASE_CONFIRM;
172
173         /* wait until flash is ready */
174         state = 0;
175         start = get_timer(0);
176
177         do {
178                 result = *addr;
179
180                 /* check timeout */
181                 if (get_timer(start) > CONFIG_SYS_FLASH_ERASE_TOUT) {
182                         MEM_FLASH_ADDR1 = CMD_READ_ARRAY;
183                         state = ERR_TIMOUT;
184                 }
185
186                 if (!state && (result & 0xFFFF) & BIT_ERASE_DONE)
187                         state = ERR_READY;
188         }
189         while (!state);
190         if (state == ERR_READY)
191                 state = ERR_OK;
192
193         MEM_FLASH_ADDR1 = CMD_READ_ARRAY;
194
195         return state;
196 }
197
198 int flash_erase (flash_info_t * info, int s_first, int s_last)
199 {
200         int iflag, cflag;
201         int sector;
202         int rc;
203
204         rc = ERR_OK;
205
206         if (info->flash_id == FLASH_UNKNOWN)
207         {
208                 rc = ERR_UNKNOWN_FLASH_TYPE;
209         } /* (info->flash_id == FLASH_UNKNOWN) */
210
211         if ((s_first < 0) || (s_first > s_last) || s_last >= info->sector_count)
212         {
213                 rc = ERR_INVAL;
214         }
215
216         cflag = icache_status ();
217         icache_disable ();
218         iflag = disable_interrupts ();
219
220         for (sector = s_first; (sector <= s_last) && (rc == ERR_OK); sector++) {
221
222                 if (info->protect[sector])
223                 {
224                         putc('P'); /*  protected sector will not erase */
225                 }
226                 else
227                 {
228                         /* erase on unprotected sector */
229                         puts("E\b");
230                         switch (info->flash_id & FLASH_VENDMASK)
231                         {
232                         case (AMD_MANUFACT & FLASH_VENDMASK):
233                                 rc = amd_flash_erase_sector(info,sector);
234                                 break;
235                         case (FREESCALE_MANUFACT & FLASH_VENDMASK):
236                                 rc = cfm_flash_erase_sector(info,sector);
237                                 break;
238                         default:
239                                 return ERR_UNKNOWN_FLASH_VENDOR;
240                         }
241                         putc('.');
242                 }
243         }
244         if (rc!=ERR_OK)
245         {
246                 printf ("\n   ");
247                 flash_perror (rc);
248         }
249         else
250         {
251                 printf (" done\n");
252         }
253
254         udelay (10000); /* allow flash to settle - wait 10 ms */
255
256         if (iflag)
257                 enable_interrupts ();
258
259         if (cflag)
260                 icache_enable ();
261
262         return rc;
263 }
264
265 volatile static int amd_write_word (flash_info_t * info, ulong dest, u16 data)
266 {
267         volatile u16 *addr;
268         ulong result;
269         int cflag, iflag;
270         int state;
271         ulong start;
272
273         /*
274          * Check if Flash is (sufficiently) erased
275          */
276         addr = (volatile u16 *) dest;
277
278         result = *addr;
279         if ((result & data) != data)
280                 return ERR_NOT_ERASED;
281
282         /*
283          * Disable interrupts which might cause a timeout
284          * here. Remember that our exception vectors are
285          * at address 0 in the flash, and we don't want a
286          * (ticker) exception to happen while the flash
287          * chip is in programming mode.
288          */
289
290         cflag = icache_status ();
291         icache_disable ();
292         iflag = disable_interrupts ();
293
294         MEM_FLASH_ADDR1 = CMD_UNLOCK1;
295         MEM_FLASH_ADDR2 = CMD_UNLOCK2;
296         MEM_FLASH_ADDR1 = CMD_PROGRAM;
297         *addr = data;
298
299         /* arm simple, non interrupt dependent timer */
300         start = get_timer(0);
301
302         /* wait until flash is ready */
303         state = 0;
304         do {
305                 result = *addr;
306
307                 /* check timeout */
308                 if (get_timer(start) > CONFIG_SYS_FLASH_ERASE_TOUT) {
309                                 state = ERR_TIMOUT;
310                 }
311                 if (!state && ((result & BIT_RDY_MASK) == (data & BIT_RDY_MASK)))
312                         state = ERR_READY;
313
314         } while (!state);
315
316         *addr = CMD_READ_ARRAY;
317
318         if (state == ERR_READY)
319                 state = ERR_OK;
320         if ((*addr != data) && (state != ERR_TIMOUT))
321                 state = ERR_PROG_ERROR;
322
323         if (iflag)
324                 enable_interrupts ();
325
326         if (cflag)
327                 icache_enable ();
328
329         return state;
330 }
331
332 int amd_flash_write_buff(flash_info_t * info, uchar * src, ulong addr, ulong cnt)
333 {
334         int rc;
335         ulong dest;
336         u16 data;
337
338         rc = ERR_OK;
339         if (addr & 1)
340         {
341                 debug ("Byte alignment not supported\n");
342                 rc = ERR_ALIGN;
343         }
344         if (cnt & 1)
345         {
346                 debug ("Byte transfer not supported\n");
347                 rc = ERR_ALIGN;
348         }
349
350         dest = addr;
351         while ((cnt>=2) && (rc == ERR_OK))
352         {
353                 data = *((volatile u16 *) src);
354                 rc=amd_write_word (info,dest,data);
355                 src +=2;
356                 dest +=2;
357                 cnt -=2;
358         }
359         return rc;
360 }
361
362 int write_buff (flash_info_t * info, uchar * src, ulong addr, ulong cnt)
363 {
364         int rc;
365
366         switch (info->flash_id & FLASH_VENDMASK)
367         {
368                 case (AMD_MANUFACT & FLASH_VENDMASK):
369                         rc = amd_flash_write_buff(info,src,addr,cnt);
370                         break;
371                 case (FREESCALE_MANUFACT & FLASH_VENDMASK):
372                         rc = cfm_flash_write_buff(info,src,addr,cnt);
373                         break;
374                 default:
375                         rc = ERR_UNKNOWN_FLASH_VENDOR;
376         }
377         return rc;
378
379 }
380 int amd_flash_protect(flash_info_t * info,long sector,int prot)
381 {
382         int rc;
383         rc= ERR_OK;
384         if (prot)
385         {
386                 info->protect[sector]=1;
387         }
388         else
389         {
390                 info->protect[sector]=0;
391         }
392         return rc;
393 }
394
395 #ifdef CONFIG_SYS_FLASH_PROTECTION
396
397 int flash_real_protect(flash_info_t * info,long sector,int prot)
398 {
399         int rc;
400
401         switch (info->flash_id & FLASH_VENDMASK)
402         {
403                 case (AMD_MANUFACT & FLASH_VENDMASK):
404                         rc = amd_flash_protect(info,sector,prot);
405                         break;
406                 case (FREESCALE_MANUFACT & FLASH_VENDMASK):
407                         rc = cfm_flash_protect(info,sector,prot);
408                         break;
409                 default:
410                         rc = ERR_UNKNOWN_FLASH_VENDOR;
411         }
412         return rc;
413 }
414
415 #endif