6 * Wolfgang Denk, DENX Software Engineering, wd@denx.de.
8 * See file CREDITS for list of people who contributed to this
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.
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.
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,
29 #include <asm/u-boot.h>
30 #include <asm/processor.h>
32 flash_info_t flash_info[CFG_MAX_FLASH_BANKS]; /* info for FLASH chips */
35 #define FLASH_WORD_SIZE unsigned long
36 #define FLASH_ID_MASK 0xFFFFFFFF
38 /*-----------------------------------------------------------------------
41 /* stolen from esteem192e/flash.c */
42 ulong flash_get_size (volatile FLASH_WORD_SIZE *addr, flash_info_t *info);
44 static int write_word (flash_info_t *info, ulong dest, ulong data);
45 static void flash_get_offsets (ulong base, flash_info_t *info);
48 /*-----------------------------------------------------------------------
51 unsigned long flash_init (void)
53 unsigned long size_b0, size_b1;
56 unsigned long base_b0, base_b1;
57 volatile FLASH_WORD_SIZE* flash_base;
59 /* Init: no FLASHes known */
60 for (i=0; i<CFG_MAX_FLASH_BANKS; ++i) {
61 flash_info[i].flash_id = FLASH_UNKNOWN;
64 /* Static FLASH Bank configuration here */
65 /* Test for 8M Flash first */
66 debug ("\n## Get flash bank 1 size @ 0x%08x\n",FLASH_BASE0_8M_PRELIM);
67 flash_base = (volatile FLASH_WORD_SIZE*)(FLASH_BASE0_8M_PRELIM);
68 size_b0 = flash_get_size(flash_base, &flash_info[0]);
70 if (flash_info[0].flash_id == FLASH_UNKNOWN) {
71 printf ("## Unknown FLASH on Bank 0 - Size = 0x%08lx = %ld MB\n",
72 size_b0, size_b0<<20);
76 if (size_b0 < 8*1024*1024) {
77 /* Not quite 8M, try 4M Flash base address */
78 debug ("\n## Get flash bank 1 size @ 0x%08x\n",FLASH_BASE0_4M_PRELIM);
79 flash_base = (volatile FLASH_WORD_SIZE*)(FLASH_BASE0_4M_PRELIM);
80 size_b0 = flash_get_size(flash_base, &flash_info[0]);
83 if (flash_info[0].flash_id == FLASH_UNKNOWN) {
84 printf ("## Unknown FLASH on Bank 0 - Size = 0x%08lx = %ld MB\n",
85 size_b0, size_b0<<20);
90 if (CFG_MAX_FLASH_BANKS == 1) {
92 flash_get_offsets ((ulong)flash_base, &flash_info[0]);
94 /* Monitor protection ON by default */
95 (void)flash_protect(FLAG_PROTECT_SET, CFG_MONITOR_BASE,
96 CFG_MONITOR_BASE+CFG_MONITOR_LEN-1, &flash_info[0]);
98 flash_info[0].size = size_b0;
102 /* We have 2 banks */
103 size_b1 = flash_get_size(flash_base, &flash_info[1]);
105 /* Re-do sizing to get full correct info */
107 mtdcr(ebccfga, pb0cr);
108 pbcr = mfdcr(ebccfgd);
109 mtdcr(ebccfga, pb0cr);
111 pbcr = (pbcr & 0x0001ffff) | base_b1 | (((size_b1/1024/1024)-1)<<17);
112 mtdcr(ebccfgd, pbcr);
116 mtdcr(ebccfga, pb1cr);
117 pbcr = mfdcr(ebccfgd);
118 mtdcr(ebccfga, pb1cr);
119 base_b0 = base_b1 - size_b0;
120 pbcr = (pbcr & 0x0001ffff) | base_b0 | (((size_b0/1024/1024)-1)<<17);
121 mtdcr(ebccfgd, pbcr);
124 size_b0 = flash_get_size((volatile FLASH_WORD_SIZE *)base_b0, &flash_info[0]);
125 flash_get_offsets (base_b0, &flash_info[0]);
127 /* monitor protection ON by default */
128 (void)flash_protect(FLAG_PROTECT_SET, CFG_MONITOR_BASE,
129 CFG_MONITOR_BASE+CFG_MONITOR_LEN-1, &flash_info[0]);
132 /* Re-do sizing to get full correct info */
133 size_b1 = flash_get_size((volatile FLASH_WORD_SIZE *)base_b1, &flash_info[1]);
134 flash_get_offsets (base_b1, &flash_info[1]);
136 /* monitor protection ON by default */
137 (void)flash_protect(FLAG_PROTECT_SET, base_b1+size_b1-CFG_MONITOR_LEN,
138 base_b1+size_b1-1, &flash_info[1]);
140 /* monitor protection OFF by default (one is enough) */
141 (void)flash_protect(FLAG_PROTECT_CLEAR, base_b0+size_b0-CFG_MONITOR_LEN,
142 base_b0+size_b0-1, &flash_info[0]);
144 flash_info[1].flash_id = FLASH_UNKNOWN;
145 flash_info[1].sector_count = -1;
148 flash_info[0].size = size_b0;
149 flash_info[1].size = size_b1;
150 return (size_b0 + size_b1);
154 /*-----------------------------------------------------------------------
155 This code is specific to the AM29DL163/AM29DL232 for the QS850/QS823.
158 static void flash_get_offsets (ulong base, flash_info_t *info)
161 long large_sect_size;
162 long small_sect_size;
164 /* set up sector start adress table */
165 large_sect_size = info->size / (info->sector_count - 8 + 1);
166 small_sect_size = large_sect_size / 8;
168 if (info->flash_id & FLASH_BTYPE) {
170 /* set sector offsets for bottom boot block type */
171 for (i = 0; i < 7; i++) {
172 info->start[i] = base;
173 base += small_sect_size;
176 for (; i < info->sector_count; i++) {
177 info->start[i] = base;
178 base += large_sect_size;
183 /* set sector offsets for top boot block type */
184 for (i = 0; i < (info->sector_count - 8); i++) {
185 info->start[i] = base;
186 base += large_sect_size;
189 for (; i < info->sector_count; i++) {
190 info->start[i] = base;
191 base += small_sect_size;
196 /*-----------------------------------------------------------------------
199 void flash_print_info (flash_info_t *info)
203 uchar botboot[]=", bottom boot sect)\n";
204 uchar topboot[]=", top boot sector)\n";
206 if (info->flash_id == FLASH_UNKNOWN) {
207 printf ("missing or unknown FLASH type\n");
211 switch (info->flash_id & FLASH_VENDMASK) {
224 case FLASH_MAN_INTEL:
228 printf ("Unknown Vendor ");
232 if (info->flash_id & 0x0001 ) {
238 switch (info->flash_id & FLASH_TYPEMASK) {
240 printf ("AM29LV160B (16 Mbit%s",boottype);
243 printf ("AM29LV160T (16 Mbit%s",boottype);
246 printf ("AM29DL163T (16 Mbit%s",boottype);
249 printf ("AM29DL163B (16 Mbit%s",boottype);
252 printf ("AM29LV320B (32 Mbit%s",boottype);
255 printf ("AM29LV320T (32 Mbit%s",boottype);
258 printf ("AM29DL323T (32 Mbit%s",boottype);
261 printf ("AM29DL323B (32 Mbit%s",boottype);
264 printf ("AM29DL322T (32 Mbit%s",boottype);
267 printf ("Unknown Chip Type\n");
271 printf (" Size: %ld MB in %d Sectors\n",
272 info->size >> 20, info->sector_count);
274 printf (" Sector Start Addresses:");
275 for (i=0; i<info->sector_count; ++i) {
278 printf (" %08lX%s", info->start[i],
279 info->protect[i] ? " (RO)" : " ");
286 /*-----------------------------------------------------------------------
287 * The following code cannot be run from FLASH!
289 ulong flash_get_size (volatile FLASH_WORD_SIZE *addr, flash_info_t *info)
292 ulong base = (ulong)addr;
293 FLASH_WORD_SIZE value;
295 /* Write auto select command: read Manufacturer ID */
298 * Note: if it is an AMD flash and the word at addr[0000]
299 * is 0x00890089 this routine will think it is an Intel
300 * flash device and may(most likely) cause trouble.
303 addr[0x0000] = 0x00900090;
304 if(addr[0x0000] != 0x00890089){
305 addr[0x0555] = 0x00AA00AA;
306 addr[0x02AA] = 0x00550055;
307 addr[0x0555] = 0x00900090;
312 case (AMD_MANUFACT & FLASH_ID_MASK):
313 info->flash_id = FLASH_MAN_AMD;
315 case (FUJ_MANUFACT & FLASH_ID_MASK):
316 info->flash_id = FLASH_MAN_FUJ;
318 case (STM_MANUFACT & FLASH_ID_MASK):
319 info->flash_id = FLASH_MAN_STM;
321 case (SST_MANUFACT & FLASH_ID_MASK):
322 info->flash_id = FLASH_MAN_SST;
324 case (INTEL_MANUFACT & FLASH_ID_MASK):
325 info->flash_id = FLASH_MAN_INTEL;
328 info->flash_id = FLASH_UNKNOWN;
329 info->sector_count = 0;
331 return (0); /* no or unknown flash */
334 value = addr[1]; /* device ID */
337 case (AMD_ID_LV160T & FLASH_ID_MASK):
338 info->flash_id += FLASH_AM160T;
339 info->sector_count = 35;
340 info->size = 0x00400000;
343 case (AMD_ID_LV160B & FLASH_ID_MASK):
344 info->flash_id += FLASH_AM160B;
345 info->sector_count = 35;
346 info->size = 0x00400000;
349 case (AMD_ID_DL163T & FLASH_ID_MASK):
350 info->flash_id += FLASH_AMDL163T;
351 info->sector_count = 39;
352 info->size = 0x00400000;
355 case (AMD_ID_DL163B & FLASH_ID_MASK):
356 info->flash_id += FLASH_AMDL163B;
357 info->sector_count = 39;
358 info->size = 0x00400000;
361 case (AMD_ID_DL323T & FLASH_ID_MASK):
362 info->flash_id += FLASH_AMDL323T;
363 info->sector_count = 71;
364 info->size = 0x00800000;
367 case (AMD_ID_DL323B & FLASH_ID_MASK):
368 info->flash_id += FLASH_AMDL323B;
369 info->sector_count = 71;
370 info->size = 0x00800000;
373 case (AMD_ID_DL322T & FLASH_ID_MASK):
374 info->flash_id += FLASH_AMDL322T;
375 info->sector_count = 71;
376 info->size = 0x00800000;
381 info->flash_id = FLASH_UNKNOWN;
382 return (0); /* => no or unknown flash */
385 flash_get_offsets(base, info);
387 /* check for protected sectors */
388 for (i = 0; i < info->sector_count; i++) {
389 /* read sector protection at sector address, (A7 .. A0) = 0x02 */
390 /* D0 = 1 if protected */
391 addr = (volatile FLASH_WORD_SIZE *)(info->start[i]);
392 info->protect[i] = addr[2] & 1;
396 * Prevent writes to uninitialized FLASH.
398 if (info->flash_id != FLASH_UNKNOWN) {
399 addr = (volatile FLASH_WORD_SIZE *)info->start[0];
400 *addr = (0x00FF00FF & FLASH_ID_MASK); /* reset bank */
407 /*-----------------------------------------------------------------------
410 int flash_erase (flash_info_t *info, int s_first, int s_last)
412 volatile FLASH_WORD_SIZE *addr=(volatile FLASH_WORD_SIZE*)(info->start[0]);
413 int flag, prot, sect, l_sect;
414 ulong start, now, last;
417 if ((s_first < 0) || (s_first > s_last)) {
418 if (info->flash_id == FLASH_UNKNOWN) {
419 printf ("- missing\n");
421 printf ("- no sectors to erase\n");
426 if ((info->flash_id == FLASH_UNKNOWN) ||
427 (info->flash_id > FLASH_AMD_COMP) ) {
428 printf ("Can't erase unknown flash type - aborted\n");
433 for (sect=s_first; sect<=s_last; ++sect) {
434 if (info->protect[sect]) {
440 printf ("- Warning: %d protected sectors will not be erased!\n",
448 /* Disable interrupts which might cause a timeout here */
449 flag = disable_interrupts();
450 addr[0x0555] = 0x00AA00AA;
451 addr[0x02AA] = 0x00550055;
452 addr[0x0555] = 0x00800080;
453 addr[0x0555] = 0x00AA00AA;
454 addr[0x02AA] = 0x00550055;
455 /* Start erase on unprotected sectors */
456 for (sect = s_first; sect<=s_last; sect++) {
457 if (info->protect[sect] == 0) { /* not protected */
458 addr = (volatile FLASH_WORD_SIZE *)(info->start[sect]);
459 addr[0] = (0x00300030 & FLASH_ID_MASK);
464 /* re-enable interrupts if necessary */
468 /* wait at least 80us - let's wait 1 ms */
472 * We wait for the last triggered sector
477 start = get_timer (0);
479 addr = (volatile FLASH_WORD_SIZE*)(info->start[l_sect]);
480 while ((addr[0] & (0x00800080&FLASH_ID_MASK)) !=
481 (0x00800080&FLASH_ID_MASK) )
483 if ((now = get_timer(start)) > CFG_FLASH_ERASE_TOUT) {
484 printf ("Timeout\n");
487 /* show that we're waiting */
488 if ((now - last) > 1000) { /* every second */
495 /* reset to read mode */
496 addr = (volatile FLASH_WORD_SIZE *)info->start[0];
497 addr[0] = (0x00F000F0 & FLASH_ID_MASK); /* reset bank */
503 /*-----------------------------------------------------------------------
504 * Copy memory to flash, returns:
507 * 2 - Flash not erased
510 int write_buff (flash_info_t *info, uchar *src, ulong addr, ulong cnt)
516 wp = (addr & ~3); /* get lower word aligned address */
519 * handle unaligned start bytes
521 if ((l = addr - wp) != 0) {
523 for (i=0, cp=wp; i<l; ++i, ++cp) {
524 data = (data << 8) | (*(uchar *)cp);
526 for (; i<4 && cnt>0; ++i) {
527 data = (data << 8) | *src++;
531 for (; cnt==0 && i<4; ++i, ++cp) {
532 data = (data << 8) | (*(uchar *)cp);
535 if ((rc = write_word(info, wp, data)) != 0) {
542 * handle word aligned part
546 for (i=0; i<4; ++i) {
547 data = (data << 8) | *src++;
549 if ((rc = write_word(info, wp, data)) != 0) {
561 * handle unaligned tail bytes
564 for (i=0, cp=wp; i<4 && cnt>0; ++i, ++cp) {
565 data = (data << 8) | *src++;
568 for (; i<4; ++i, ++cp) {
569 data = (data << 8) | (*(uchar *)cp);
572 return (write_word(info, wp, data));
575 /*-----------------------------------------------------------------------
576 * Write a word to Flash, returns:
579 * 2 - Flash not erased
581 static int write_word (flash_info_t *info, ulong dest, ulong data)
583 vu_long *addr = (vu_long*)(info->start[0]);
587 /* Check if Flash is (sufficiently) erased */
588 if ((*((vu_long *)dest) & data) != data) {
592 /* Disable interrupts which might cause a timeout here */
593 flag = disable_interrupts();
596 addr[0x0555] = 0x00AA00AA;
597 addr[0x02AA] = 0x00550055;
598 addr[0x0555] = 0x00A000A0;
600 *((vu_long *)dest) = data;
602 /* re-enable interrupts if necessary */
606 /* data polling for D7 */
607 start = get_timer(0);
609 while ((*((vu_long *)dest) & 0x00800080) != (data & 0x00800080)) {
610 if (get_timer(start) > CFG_FLASH_WRITE_TOUT) {