]> git.kernelconcepts.de Git - karo-tx-uboot.git/blob - board/v37/flash.c
Merge branch 'u-boot/master' into u-boot-arm/master
[karo-tx-uboot.git] / board / v37 / flash.c
1 /*
2  * (C) Copyright 2003
3  * Wolfgang Denk, DENX Software Engineering, wd@denx.de.
4  *
5  * SPDX-License-Identifier:     GPL-2.0+
6  */
7
8 /*
9  * Yoo. Jonghoon, IPone, yooth@ipone.co.kr
10  * U-Boot port on RPXlite board
11  *
12  * Some of flash control words are modified. (from 2x16bit device
13  * to 4x8bit device)
14  * RPXLite board I tested has only 4 AM29LV800BB devices. Other devices
15  * are not tested.
16  *
17  * (?) Does an RPXLite board which
18  *      does not use AM29LV800 flash memory exist ?
19  *      I don't know...
20  */
21
22 #include <common.h>
23 #include <mpc8xx.h>
24
25 flash_info_t    flash_info[CONFIG_SYS_MAX_FLASH_BANKS]; /* info for FLASH chips */
26
27 /*-----------------------------------------------------------------------
28  * Functions
29  */
30 static ulong flash_get_size ( short manu, short dev_id, flash_info_t *info);
31 static int write_word (flash_info_t *info, ulong dest, ulong data);
32 static void flash_get_offsets (ulong base, flash_info_t *info, int two_chips);
33 static void flash_get_id_word( void *ptr,  short *ptr_manuf, short *ptr_dev_id);
34 static void flash_get_id_long( void *ptr,  short *ptr_manuf, short *ptr_dev_id);
35
36 /*-----------------------------------------------------------------------
37  */
38
39 unsigned long flash_init (void)
40 {
41         volatile immap_t     *immap  = (immap_t *)CONFIG_SYS_IMMR;
42         volatile memctl8xx_t *memctl = &immap->im_memctl;
43         unsigned long size_b0, size_b1;
44         short manu, dev_id;
45         int i;
46
47         /* Init: no FLASHes known */
48         for (i=0; i<CONFIG_SYS_MAX_FLASH_BANKS; ++i) {
49                 flash_info[i].flash_id = FLASH_UNKNOWN;
50         }
51
52         /* Do sizing to get full correct info */
53
54         flash_get_id_word((void*)CONFIG_SYS_FLASH_BASE0,&manu,&dev_id);
55
56         size_b0 = flash_get_size(manu, dev_id, &flash_info[0]);
57
58         flash_get_offsets (CONFIG_SYS_FLASH_BASE0, &flash_info[0],0);
59
60         memctl->memc_or0 = CONFIG_SYS_OR_TIMING_FLASH | (0 - size_b0);
61
62 #if CONFIG_SYS_MONITOR_BASE >= CONFIG_SYS_FLASH_BASE0
63         /* monitor protection ON by default */
64         flash_protect(FLAG_PROTECT_SET,
65                       CONFIG_SYS_MONITOR_BASE,
66                       CONFIG_SYS_MONITOR_BASE+monitor_flash_len-1,
67                       &flash_info[0]);
68 #endif
69
70         flash_get_id_long((void*)CONFIG_SYS_FLASH_BASE1,&manu,&dev_id);
71
72         size_b1 = 2 * flash_get_size(manu, dev_id, &flash_info[1]);
73
74         flash_get_offsets(CONFIG_SYS_FLASH_BASE1, &flash_info[1],1);
75
76         memctl->memc_or1 = CONFIG_SYS_OR_TIMING_FLASH | (0 - size_b1);
77
78         flash_info[0].size = size_b0;
79         flash_info[1].size = size_b1;
80
81         return (size_b0+size_b1);
82 }
83
84 /*-----------------------------------------------------------------------
85  */
86 static void flash_get_offsets (ulong base, flash_info_t *info, int two_chips)
87 {
88         int i, addr_shift;
89         vu_short *addr = (vu_short*)base;
90
91         addr[0x555] = 0x00AA ;
92         addr[0xAAA] = 0x0055 ;
93         addr[0x555] = 0x0090 ;
94
95         addr_shift = (two_chips ? 2 : 1 );
96
97         /* set up sector start address table */
98         if (info->flash_id & FLASH_BTYPE) {
99                 /* set sector offsets for bottom boot block type        */
100                 info->start[0] = base + (0x00000000<<addr_shift);
101                 info->start[1] = base + (0x00002000<<addr_shift);
102                 info->start[2] = base + (0x00003000<<addr_shift);
103                 info->start[3] = base + (0x00004000<<addr_shift);
104                 for (i = 4; i < info->sector_count; i++) {
105                         info->start[i] = base + ((i-3) * (0x00008000<<addr_shift)) ;
106                 }
107         } else {
108                 /* set sector offsets for top boot block type           */
109                 i = info->sector_count - 1;
110                 info->start[i--] = base + info->size - (0x00002000<<addr_shift);
111                 info->start[i--] = base + info->size - (0x00003000<<addr_shift);
112                 info->start[i--] = base + info->size - (0x00004000<<addr_shift);
113                 for (; i >= 0; i--) {
114                         info->start[i] = base + i * (0x00008000<<addr_shift);
115                 }
116         }
117
118         /* check for protected sectors */
119         for (i = 0; i < info->sector_count; i++) {
120                 /* read sector protection at sector address, (A7 .. A0) = 0x02 */
121                 /* D0 = 1 if protected */
122                 addr = (vu_short *)(info->start[i]);
123                 info->protect[i] = addr[1<<addr_shift] & 1 ;
124         }
125
126         addr = (vu_short *)info->start[0];
127         *addr = 0xF0F0; /* reset bank */
128 }
129
130 /*-----------------------------------------------------------------------
131  */
132 void flash_print_info  (flash_info_t *info)
133 {
134         int i;
135
136         if (info->flash_id == FLASH_UNKNOWN) {
137                 printf ("missing or unknown FLASH type\n");
138                 return;
139         }
140
141         switch (info->flash_id & FLASH_VENDMASK) {
142         case FLASH_MAN_AMD:     printf ("AMD ");                break;
143         case FLASH_MAN_FUJ:     printf ("FUJITSU ");            break;
144         case FLASH_MAN_TOSH:    printf ("TOSHIBA ");            break;
145         default:                printf ("Unknown Vendor ");     break;
146         }
147
148         switch (info->flash_id & FLASH_TYPEMASK) {
149         case FLASH_AM400B:      printf ("AM29LV400B (4 Mbit, bottom boot sect)\n");
150                                 break;
151         case FLASH_AM400T:      printf ("AM29LV400T (4 Mbit, top boot sector)\n");
152                                 break;
153         case FLASH_AM800B:      printf ("AM29LV800B (8 Mbit, bottom boot sect)\n");
154                                 break;
155         case FLASH_AM800T:      printf ("AM29LV800T (8 Mbit, top boot sector)\n");
156                                 break;
157         case FLASH_AM160B:      printf ("AM29LV160B (16 Mbit, bottom boot sect)\n");
158                                 break;
159         case FLASH_AM160T:      printf ("AM29LV160T (16 Mbit, top boot sector)\n");
160                                 break;
161         case FLASH_AM320B:      printf ("AM29LV320B (32 Mbit, bottom boot sect)\n");
162                                 break;
163         case FLASH_AM320T:      printf ("AM29LV320T (32 Mbit, top boot sector)\n");
164                                 break;
165         default:                printf ("Unknown Chip Type\n");
166                                 break;
167         }
168
169         printf ("  Size: %ld MB in %d Sectors\n",
170                 info->size >> 20, info->sector_count);
171
172         printf ("  Sector Start Addresses:");
173         for (i=0; i<info->sector_count; ++i) {
174                 if ((i % 5) == 0)
175                         printf ("\n   ");
176                 printf (" %08lX%s",
177                         info->start[i],
178                         info->protect[i] ? " (RO)" : "     "
179                 );
180         }
181         printf ("\n");
182 }
183
184 /*-----------------------------------------------------------------------
185  */
186
187
188 /*-----------------------------------------------------------------------
189  */
190
191 /*
192  * The following code cannot be run from FLASH!
193  */
194
195 static void flash_get_id_word( void *ptr,  short *ptr_manuf, short *ptr_dev_id)
196 {
197         vu_short *addr = (vu_short*)ptr;
198
199         addr[0x555] = 0x00AA ;
200         addr[0xAAA] = 0x0055 ;
201         addr[0x555] = 0x0090 ;
202
203         *ptr_manuf  = addr[0];
204         *ptr_dev_id = addr[1];
205
206         addr[0] = 0xf0f0;       /* return to normal */
207 }
208
209 static void flash_get_id_long( void *ptr,  short *ptr_manuf, short *ptr_dev_id)
210 {
211         vu_short *addr = (vu_short*)ptr;
212         vu_short *addr1, *addr2, *addr3;
213
214         addr1 = (vu_short*) ( ((int)ptr) + (0x5555<<2) );
215         addr2 = (vu_short*) ( ((int)ptr) + (0x2AAA<<2) );
216         addr3 = (vu_short*) ( ((int)ptr) + (0x5555<<2) );
217
218         *addr1 = 0xAAAA;
219         *addr2 = 0x5555;
220         *addr3 = 0x9090;
221
222         *ptr_manuf  = addr[0];
223         *ptr_dev_id = addr[2];
224
225         addr[0] = 0xf0f0;       /* return to normal */
226 }
227
228 static ulong flash_get_size ( short manu, short dev_id, flash_info_t *info)
229 {
230         switch (manu) {
231         case ((short)AMD_MANUFACT):
232                 info->flash_id = FLASH_MAN_AMD;
233                 break;
234         case ((short)FUJ_MANUFACT):
235                 info->flash_id = FLASH_MAN_FUJ;
236                 break;
237         case ((short)TOSH_MANUFACT):
238                 info->flash_id = FLASH_MAN_TOSH;
239                 break;
240         default:
241                 info->flash_id = FLASH_UNKNOWN;
242                 info->sector_count = 0;
243                 info->size = 0;
244                 return (0);                     /* no or unknown flash  */
245         }
246
247
248         switch (dev_id) {
249         case ((short)TOSH_ID_FVT160):
250                 info->flash_id += FLASH_AM160T;
251                 info->sector_count = 35;
252                 info->size = 0x00200000;
253                 break;                          /* => 1 MB              */
254
255         case ((short)TOSH_ID_FVB160):
256                 info->flash_id += FLASH_AM160B;
257                 info->sector_count = 35;
258                 info->size = 0x00200000;
259                 break;                          /* => 1 MB              */
260
261         case ((short)AMD_ID_LV400T):
262                 info->flash_id += FLASH_AM400T;
263                 info->sector_count = 11;
264                 info->size = 0x00100000;
265                 break;                          /* => 1 MB              */
266
267         case ((short)AMD_ID_LV400B):
268                 info->flash_id += FLASH_AM400B;
269                 info->sector_count = 11;
270                 info->size = 0x00100000;
271                 break;                          /* => 1 MB              */
272
273         case ((short)AMD_ID_LV800T):
274                 info->flash_id += FLASH_AM800T;
275                 info->sector_count = 19;
276                 info->size = 0x00200000;
277                 break;                          /* => 2 MB              */
278
279         case ((short)AMD_ID_LV800B):
280                 info->flash_id += FLASH_AM800B;
281                 info->sector_count = 19;
282                 info->size = 0x00400000;        /*%%% Size doubled by yooth */
283                 break;                          /* => 4 MB              */
284
285         case ((short)AMD_ID_LV160T):
286                 info->flash_id += FLASH_AM160T;
287                 info->sector_count = 35;
288                 info->size = 0x00200000;
289                 break;                          /* => 4 MB              */
290
291         case ((short)AMD_ID_LV160B):
292                 info->flash_id += FLASH_AM160B;
293                 info->sector_count = 35;
294                 info->size = 0x00200000;
295                 break;                          /* => 4 MB              */
296         default:
297                 info->flash_id = FLASH_UNKNOWN;
298                 return (0);                     /* => no or unknown flash */
299
300         }
301
302         return(info->size);
303 }
304
305
306 /*-----------------------------------------------------------------------
307  */
308
309 int     flash_erase (flash_info_t *info, int s_first, int s_last)
310 {
311         vu_short *addr = (vu_short*)(info->start[0]);
312         int flag, prot, sect, l_sect;
313         ulong start, now, last;
314
315         if ((s_first < 0) || (s_first > s_last)) {
316                 if (info->flash_id == FLASH_UNKNOWN) {
317                         printf ("- missing\n");
318                 } else {
319                         printf ("- no sectors to erase\n");
320                 }
321                 return 1;
322         }
323
324         if ((info->flash_id == FLASH_UNKNOWN) ||
325             (info->flash_id > FLASH_AMD_COMP)) {
326                 printf ("Can't erase unknown flash type %08lx - aborted\n",
327                         info->flash_id);
328                 return 1;
329         }
330
331         prot = 0;
332         for (sect=s_first; sect<=s_last; ++sect) {
333                 if (info->protect[sect]) {
334                         prot++;
335                 }
336         }
337
338         if (prot) {
339                 printf ("- Warning: %d protected sectors will not be erased!\n",
340                         prot);
341         } else {
342                 printf ("\n");
343         }
344
345         l_sect = -1;
346
347         /* Disable interrupts which might cause a timeout here */
348         flag = disable_interrupts();
349
350         addr[0x555] = (vu_short)0xAAAAAAAA;
351         addr[0xAAA] = (vu_short)0x55555555;
352         addr[0x555] = (vu_short)0x80808080;
353         addr[0x555] = (vu_short)0xAAAAAAAA;
354         addr[0xAAA] = (vu_short)0x55555555;
355
356         /* Start erase on unprotected sectors */
357         for (sect = s_first; sect<=s_last; sect++) {
358                 if (info->protect[sect] == 0) { /* not protected */
359                         addr = (vu_short *)(info->start[sect]) ;
360                         addr[0] = (vu_short)0x30303030 ;
361                         l_sect = sect;
362                 }
363         }
364
365         /* re-enable interrupts if necessary */
366         if (flag)
367                 enable_interrupts();
368
369         /* wait at least 80us - let's wait 1 ms */
370         udelay (1000);
371
372         /*
373          * We wait for the last triggered sector
374          */
375         if (l_sect < 0)
376                 goto DONE;
377
378         start = get_timer (0);
379         last  = start;
380         addr = (vu_short *)(info->start[l_sect]);
381         while ((addr[0] & 0x8080) != 0x8080) {
382                 if ((now = get_timer(start)) > CONFIG_SYS_FLASH_ERASE_TOUT) {
383                         printf ("Timeout\n");
384                         return 1;
385                 }
386                 /* show that we're waiting */
387                 if ((now - last) > 1000) {      /* every second */
388                         putc ('.');
389                         last = now;
390                 }
391         }
392
393 DONE:
394         /* reset to read mode */
395         addr = (vu_short *)info->start[0];
396         addr[0] = (vu_short)0xF0F0F0F0; /* reset bank */
397
398         printf (" done\n");
399         return 0;
400 }
401
402 /*-----------------------------------------------------------------------
403  * Copy memory to flash, returns:
404  * 0 - OK
405  * 1 - write timeout
406  * 2 - Flash not erased
407  */
408
409 int write_buff (flash_info_t *info, uchar *src, ulong addr, ulong cnt)
410 {
411         ulong cp, wp, data;
412         int i, l, rc;
413
414         wp = (addr & ~3);       /* get lower word aligned address */
415
416         /*
417          * handle unaligned start bytes
418          */
419         if ((l = addr - wp) != 0) {
420                 data = 0;
421                 for (i=0, cp=wp; i<l; ++i, ++cp) {
422                         data = (data << 8) | (*(uchar *)cp);
423                 }
424                 for (; i<4 && cnt>0; ++i) {
425                         data = (data << 8) | *src++;
426                         --cnt;
427                         ++cp;
428                 }
429                 for (; cnt==0 && i<4; ++i, ++cp) {
430                         data = (data << 8) | (*(uchar *)cp);
431                 }
432
433                 if ((rc = write_word(info, wp, data)) != 0) {
434                         return (rc);
435                 }
436                 wp += 4;
437         }
438
439         /*
440          * handle word aligned part
441          */
442         while (cnt >= 4) {
443                 data = 0;
444                 for (i=0; i<4; ++i) {
445                         data = (data << 8) | *src++;
446                 }
447                 if ((rc = write_word(info, wp, data)) != 0) {
448                         return (rc);
449                 }
450                 wp  += 4;
451                 cnt -= 4;
452         }
453
454         if (cnt == 0) {
455                 return (0);
456         }
457
458         /*
459          * handle unaligned tail bytes
460          */
461         data = 0;
462         for (i=0, cp=wp; i<4 && cnt>0; ++i, ++cp) {
463                 data = (data << 8) | *src++;
464                 --cnt;
465         }
466         for (; i<4; ++i, ++cp) {
467                 data = (data << 8) | (*(uchar *)cp);
468         }
469
470         return (write_word(info, wp, data));
471 }
472
473 /*-----------------------------------------------------------------------
474  * Write a word to Flash, returns:
475  * 0 - OK
476  * 1 - write timeout
477  * 2 - Flash not erased
478  */
479 static int write_word (flash_info_t *info, ulong dest, ulong data)
480 {
481         vu_short *addr = (vu_short *)(info->start[0]);
482         vu_short sdata;
483
484         ulong start;
485         int flag;
486
487         /* Check if Flash is (sufficiently) erased */
488         if ((*((vu_long *)dest) & data) != data) {
489                 return (2);
490         }
491
492         /* First write upper 16 bits */
493         sdata = (short)(data>>16);
494
495         /* Disable interrupts which might cause a timeout here */
496         flag = disable_interrupts();
497
498         addr[0x555] = 0xAAAA;
499         addr[0xAAA] = 0x5555;
500         addr[0x555] = 0xA0A0;
501
502         *((vu_short *)dest) = sdata;
503
504         /* re-enable interrupts if necessary */
505         if (flag)
506                 enable_interrupts();
507
508         /* data polling for D7 */
509         start = get_timer (0);
510         while ((*((vu_short *)dest) & 0x8080) != (sdata & 0x8080)) {
511                 if (get_timer(start) > CONFIG_SYS_FLASH_WRITE_TOUT) {
512                         return (1);
513                 }
514         }
515
516         /* Now write lower 16 bits */
517         sdata = (short)(data&0xffff);
518
519         /* Disable interrupts which might cause a timeout here */
520         flag = disable_interrupts();
521
522         addr[0x555] = 0xAAAA;
523         addr[0xAAA] = 0x5555;
524         addr[0x555] = 0xA0A0;
525
526         *((vu_short *)dest + 1) = sdata;
527
528         /* re-enable interrupts if necessary */
529         if (flag)
530                 enable_interrupts();
531
532         /* data polling for D7 */
533         start = get_timer (0);
534         while ((*((vu_short *)dest + 1) & 0x8080) != (sdata & 0x8080)) {
535                 if (get_timer(start) > CONFIG_SYS_FLASH_WRITE_TOUT) {
536                         return (1);
537                 }
538         }
539         return (0);
540 }
541
542 /*-----------------------------------------------------------------------
543  */