#define ID_AM29DL800B 0x22CB
#define ID_AM29LV800T 0x22DA
#define ID_AM29LV800B 0x225B
-#define ID_AM29LV400B 0x22BA
+#define ID_STM29W320EB 0x2257
+#define ID_STM29W640FB 0x22fd
+//#define ID_AM29LV400B 0x22BA
#define ID_AM29LV200BT 0x223B
#define ID_AM29LV160B 0x2249
#define ID_MX29LV320AT 0x22A7
#define ID_AM29LV320B 0x22F9
#define ID_MX29LV320AB 0x22A8
-#define ID_MX29LV640BT 0x22C9
+//#define ID_MX29LV640BT 0x22C9
#define ID_AM29LV320M 0x227E
#define ID_AM29LV320MB 0x2200
#define ID_AM29LV320MT 0x2201
+#define ID_W19L320SB 0x222A
+#define ID_W19L320ST 0x22BA
+#define ID_K8D3216UB 0x22a2
+#define ID_K8D3216UT 0x22a0
+#define ID_K8D6316UB 0x22e2
+#define ID_K8D1716UB 0x2277
+#define ID_K8D1716UT 0x2275
+
#define ID_SST39VF200A 0x2789
#define ID_SST39VF400A 0x2780
{ID_AM29DL800B, "AM29DL800B"}, \
{ID_AM29LV800T, "AM29LV800T"}, \
{ID_AM29LV800B, "AM29LV800B"}, \
- {ID_AM29LV400B, "AM29LV400B"}, \
{ID_AM29LV200BT, "AM29LV200BT"}, \
{ID_AM29LV160B, "AM29LV160B"}, \
{ID_AM29LV160T, "AM29LV160T"}, \
{ID_AM29LV320M, "AM29LV320M"}, \
{ID_AM29LV320MB, "AM29LV320MB"}, \
{ID_AM29LV320MT, "AM29LV320MT"}, \
- {ID_MX29LV640BT, "MX29LV640BT"}, \
{ID_SST39VF200A, "SST39VF200A"}, \
{ID_SST39VF400A, "SST39VF400A"}, \
{ID_SST39VF800A, "SST39VF800A"}, \
{ID_I28F320C3T, "I28F320C3T"}, \
{ID_I28F320C3B, "I28F320C3B"}, \
{ID_I28F640J3, "I28F640J3"}, \
+ {ID_W19L320SB, "W19L320SB"}, \
+ {ID_W19L320ST, "W19L320ST"}, \
+ {ID_K8D3216UB,"K8D3216UB"}, \
+ {ID_K8D3216UT,"K8D3216UT"},{ID_K8D6316UB,"K8D6316UB"},{ID_K8D1716UB,"K8D1716UB"}, \
+ {ID_K8D1716UT,"K8D1716UT"}, \
+ {ID_STM29W320EB,"STM29W320EB"}, \
+ {ID_STM29W640FB,"STM29W640FB"}, \
{0, ""} \
}
static int cfi_flash_get_cfi(struct cfi_query *query, unsigned short *cfi_struct,
int flashFamily);
+//swda add,06/27/2006
+static int DiagLedBlinking(void);
+#define T200ms ((200 * HZ) / 1000) // ~200 ms
+#define T100ms ((100 * HZ) / 1000) // ~100 ms
+//swda add end
/** Variables. **/
static flash_device_info_t flash_cfi_dev =
cfi_flash_get_total_size,
cfi_flash_get_total_size
};
-
+unsigned short device_id;
+unsigned short man_id;
/*********************************************************************/
/* 'meminfo' should be a pointer, but most C compilers will not */
/* allocate static storage for a pointer without calling */
0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff
};
+#if defined (CONFIG_BCM96338)
+unsigned long get_flash_base(unsigned long size)
+{
+ static unsigned long flash_base = FLASH_BASE;
+ if (size > 0x10000000) {
+ flash_base = size;
+ }
+ else if (size) {
+ unsigned long fsize = 8 * 1024;
+ unsigned long fbase = 0x20000000;
+ unsigned long frmap;
+
+ for (frmap = 0; frmap < 17; frmap++) {
+ if (size == fsize) {
+ fbase -= fsize;
+ if (fbase > 0x1fc00000) fbase = 0x1fc00000;
+ *(volatile unsigned long *)0xfffe3160 = fbase | frmap;
+ flash_base = (unsigned long)(fbase|0xa0000000);
+ break;
+ }
+ fsize <<= 1;
+ }
+ }
+
+ return flash_base;
+}
+#endif
+
+#if defined (CONFIG_BCM96348)
+/* denny 08/17/04' add, reconfigure and obtin flash base address */
+unsigned long get_flash_base(unsigned long size)
+{
+ static unsigned long flash_base = FLASH_BASE;
+
+ if (size > 0x10000000) {
+ flash_base = size;
+ }
+ else if (size) {
+ unsigned long fsize = 8 * 1024;
+ unsigned long fbase = 0x20000000;
+ unsigned long frmap;
+
+ for (frmap = 0; frmap < 17; frmap++) {
+ if (size == fsize) {
+ fbase -= fsize;
+ if (fbase > 0x1fc00000) fbase = 0x1fc00000;
+ *(volatile unsigned long *)MPI_BASE = fbase | frmap;
+ flash_base = (unsigned long)(fbase|0xa0000000);
+ break;
+ }
+ fsize <<= 1;
+ }
+ }
+
+ return flash_base;
+}
+#endif
+
+#ifdef CONFIG_CS1
+unsigned long get_flash2_base(unsigned long size)
+{
+ static unsigned long flash2_base = FLASH_BASE;
+
+ if (size == -1) {
+ *(volatile unsigned long *)0xfffe2008 = 0;
+ *(volatile unsigned long *)0xfffe200c = 0;
+ flash2_base = FLASH_BASE;
+ }
+ else if (size > 0xa0000000) {
+ flash2_base = size;
+ }
+ else if (size) {
+ unsigned long fsize = 8 * 1024;
+ unsigned long fbase = *(volatile unsigned long *)0xfffe2000 & ~0xf;
+ unsigned long frmap;
+
+ for (frmap = 0; frmap < 17; frmap++) {
+ if (size == fsize) {
+ fbase -= fsize;
+ *(volatile unsigned long *)0xfffe200c = *(volatile unsigned long *)0xfffe2004;
+ *(volatile unsigned long *)0xfffe2008 = fbase | frmap;
+ flash2_base = (unsigned long)(fbase|0xa0000000);
+ break;
+ }
+ fsize <<= 1;
+ }
+ }
+
+ return flash2_base;
+}
+#endif
+/* end */
/*********************************************************************/
/* Init_flash is used to build a sector table from the information */
struct flash_name_from_id *fnfi_ptr;
int i=0, j=0, count=0;
int basecount=0L;
- unsigned short device_id;
int flipCFIGeometry = FALSE;
*flash_info = &flash_cfi_dev;
break;
case ID_AM29DL800B:
case ID_AM29LV800B:
- case ID_AM29LV400B:
+// case ID_AM29LV400B:
case ID_AM29LV160B:
case ID_AM29LV320B:
case ID_MX29LV320AB:
case ID_AM29LV320T:
case ID_MX29LV320AT:
case ID_AM29LV320MT:
- case ID_AM29LV200BT:
- case ID_MX29LV640BT:
+ case ID_W19L320ST:
+ case ID_W19L320SB:
+ case ID_K8D3216UB:
+ case ID_K8D6316UB:
+ case ID_K8D1716UB:
+ case ID_K8D1716UT:
+ case ID_K8D3216UT:
+ case ID_STM29W320EB:
+ case ID_STM29W640FB:
+ case 0x43:
flashFamily = FLASH_AMD;
break;
case ID_SST39VF200A:
return FLASH_API_ERROR;
}
}
+#if defined (CONFIG_BCM96338)
+ volatile unsigned int *cs = (volatile unsigned int *)0xfffe3160;
+ /* reconfigure CS0 and flash base */
+ get_flash_base(query.device_size);
+
+ printk("Flash Config: ");
+ printk("CS0(%x,%x),", cs[0], cs[1]);
+ printk("Base(%x),", (unsigned int)get_flash_base(0));
+ printk("Size(%dMB)\n", (query.device_size)>>20);
+#endif
+
+#if defined (CONFIG_BCM96348) || defined (CONFIG_BCM96358)
+
+/* denny 08/17/04' add, reconfigure the CS0 and CS1 for flash */
+ {
+
+ volatile unsigned int *cs = (volatile unsigned int *)MPI_BASE;
+ if (device_id == ID_AM29LV320MB || device_id == ID_AM29LV320MT)
+ *(volatile unsigned int*)(MPI_BASE+4) |= 0x0000000e; /* if spansion flash CS0 wait time -> Three */
+
+#if defined (CONFIG_BCM96348)
+ /* reconfigure CS0 and flash base */
+ get_flash_base(query.device_size);
+
+#ifdef CONFIG_CS1
+ struct cfi_query query2;
+ /* try to detection CS1 for flash base */
+ get_flash_base(get_flash2_base(0x100000));
+ if (flash_get_cfi(&query2, 0,flashFamily) == -1) {
+ get_flash2_base(-1);
+ get_flash_base(query.device_size);
+ }
+ else {
+ /* reconfigure CS0 and flash base */
+ get_flash_base(query.device_size);
+ /* set flash base value */
+ get_flash_base(get_flash2_base(query2.device_size));
+ #if DEBUG_FLASH
+ printk("query.num_erase_blocks = %x\n", query.num_erase_blocks);
+ printk("query.device_size = %x\n", query.device_size);
+ printk("query2.num_erase_blocks = %x\n", query2.num_erase_blocks);
+ printk("query2.device_size = %x\n", query2.device_size);
+ printk("flash_base = %x\n", get_flash_base(0));
+ #endif
+ for (i=0; i<query.num_erase_blocks; i++)
+ memcpy(&query.erase_block[i+query2.num_erase_blocks], &query.erase_block[i], sizeof(query.erase_block[0]));
+ for (i=0; i<query2.num_erase_blocks; i++)
+ memcpy(&query.erase_block[i], &query2.erase_block[i], sizeof(query.erase_block[0]));
+ query.num_erase_blocks += query2.num_erase_blocks;
+ query.device_size += query2.device_size;
+ }
+#endif /* CS1 */
+#endif /* 6348 */
+#endif /* 6348 || 6358 */
+#if defined (CONFIG_BCM96348) || defined (CONFIG_BCM96358)
+
+ #if DEBUG_FLASH
+ printk("query.num_erase_blocks = %x\n", query.num_erase_blocks);
+ printk("query.device_size = %x\n", query.device_size);
+ printk("flash_base = %x\n", get_flash_base(0));
+ #endif
+ printk("Flash Config: ");
+ printk("CS0(%x,%x),", cs[0], cs[1]);
+#if defined (CONFIG_BCM96348)
+ if (cs[2]) printk("CS1(%x,%x) ", cs[2], cs[3]);
+ printk("Base(%x),", (unsigned int)get_flash_base(0));
+#endif
+ printk("Size(%dMB)\n", (query.device_size)>>20);
+ }
+/* end */
+#endif
// need to determine if it top or bottom boot here
switch (device_id)
{
case ID_AM29DL800B:
case ID_AM29LV800B:
- case ID_AM29LV400B:
+// case ID_AM29LV400B:
case ID_AM29LV160B:
case ID_AM29LV320B:
case ID_MX29LV320AB:
case ID_I28F640J3:
case ID_I28F160C3T:
case ID_I28F320C3T:
- case ID_SST39VF3201:
- case ID_SST39VF6401:
case ID_SST39VF200A:
case ID_SST39VF400A:
case ID_SST39VF800A:
+ case ID_K8D1716UB:
+ case ID_K8D3216UB:
+ case ID_K8D6316UB:
+ case ID_STM29W320EB:
+ case ID_STM29W640FB:
+ case ID_SST39VF1601:
+ case ID_SST39VF3201:
+ case ID_SST39VF6401:
+ case ID_W19L320SB:
+ case 0x43: // for Toshiba 58FVB160FT-85
flipCFIGeometry = FALSE;
break;
case ID_AM29DL800T:
case ID_MX29LV320AT:
case ID_AM29LV320MT:
case ID_AM29LV200BT:
- case ID_SST39VF1601:
- case ID_MX29LV640BT:
+// case ID_MX29LV640BT:
+ case ID_K8D1716UT:
+ case ID_K8D3216UT:
+ case ID_W19L320ST:
flipCFIGeometry = TRUE;
break;
default:
+ printk("Flash memory not supported! Device id = %x\n", device_id);
return FLASH_API_ERROR;
}
break;
}
}
+ if (fnfi_ptr->fnfi_id == 0) strcpy(flash_cfi_dev.flash_device_name,"UNKNOWN");
}
return (FLASH_API_OK);
/*********************************************************************/
static unsigned char *cfi_flash_get_memptr(unsigned short sector)
{
+#if defined (CONFIG_BCM96348) || defined(CONFIG_BCM96338)
+ unsigned char *memptr = (unsigned char*)
+ (get_flash_base(0) + meminfo.sec[sector].base);
+#endif
+#if defined (CONFIG_BCM96358)
unsigned char *memptr = (unsigned char*)
(FLASH_BASE + meminfo.sec[sector].base);
+#endif
return (memptr);
}
{
int blk_start, i;
int last_blk = cfi_flash_get_numsectors();
- int relative_addr = addr - (int) FLASH_BASE;
+#if defined (CONFIG_BCM96348) || defined(CONFIG_BCM96338)
+ int relative_addr = addr - (int) get_flash_base(0);
+#endif
+#if defined (CONFIG_BCM96358)
+ int relative_addr = addr - (int) FLASH_BASE;
+#endif
for(blk_start=0, i=0; i < relative_addr && blk_start < last_blk; blk_start++)
i += cfi_flash_get_sector_size(blk_start);
if ((nbytes | offset) & 1) {
return FLASH_API_ERROR;
}
+if (device_id == 0x43) {
+ volatile UINT16* flashptr;
+ volatile UINT16* dst;
+ int stat = STATUS_READY ;
+ int retry = 0, retried = 0;
+
+ flashptr = (UINT16 *)flash_get_memptr(sector);
+
+ dst = &flashptr[offset/2]; /* (byte offset) */
+
+again:
+
+#if 0
+ /* Check to see if we're in unlock bypass mode */
+ flashptr[0] = 0xF0; /* reset device to read mode */
+
+ if ((stat=flash_wait(sector)) != STATUS_READY) {
+ printk("1.error\n");
+ return (byte*)src - buf;
+ }
+#else
+ /* reset device to read mode */
+ cfi_flash_command(FLASH_RESET, 0, 0, 0);
+#endif
+
+ while (nbytes > 0) {
+
+ //swda add,06/27/2006
+ if ( (nbytes%1024) == 0 ) {
+ DiagLedBlinking();
+ }
+ //swda add end
+
+ flashptr[0x555] = 0xAA; /* unlock 1 */
+ flashptr[0x2AA] = 0x55; /* unlock 2 */
+
+ flashptr[0x555] = 0xA0;
+ *dst = *src;
+
+ if ((stat=cfi_flash_wait(sector, offset, *src)) != STATUS_READY) {
+ printk("2.error\n");
+ break;
+ }
+ dst++;
+ src++;
+ nbytes -= 2;
+ offset += 2;
+ }
+
+ if (stat != STATUS_READY || nbytes != 0) {
+ if (retry-- > 0) {
+ ++retried;
+#if 0
+ --dst, --src; /* back up */
+#endif
+ goto again; /* and retry the last word */
+ }
+
+ cfi_flash_command(FLASH_RESET,sector,0,0);
+ }
+
+
+} else if (device_id == ID_AM29LV320MB && ((man_id & 0x00ff) != 0xda)) {
+
+ volatile UINT16* flashptr;
+ volatile UINT16* dst;
+ int stat = STATUS_READY ;
+ UINT16 d1;
+ UINT16* retrydst;
+ UINT16* retrysrc;
+ int i=0, k=0 ,retryoffset ;
+ //printk("\nsector %d write %d bytes to offset %d\n",sector,nbytes,offset);
+ //printk("...........................\n");
+ //printk("..\n");
+
+ flashptr = (UINT16 *)flash_get_memptr(sector);
+
+ dst = &flashptr[offset/2]; /* (byte offset) */
+
+ cfi_flash_command(FLASH_RESET, 0, 0, 0);
+
+ while (nbytes > 0) {
+
+ retrydst = (UINT16 *)dst;
+ retrysrc = src;
+ retryoffset = offset;
+
+ //swda add,06/27/2006
+ if ( (nbytes%1024) == 0 ) {
+ DiagLedBlinking();
+ }
+ //swda add end
+
+ flashptr[0x555] = 0xAA; /* unlock 1 */
+ flashptr[0x2AA] = 0x55; /* unlock 2 */
+
+ flashptr[0] = 0x25;
+ k = (nbytes>32) ? 15 : nbytes/2-1;
+
+ flashptr[0] = k;
+ for ( i=0; i < k; i++) { *dst=*src; dst++;src++; offset+=2; } /*total k write*/
+ *dst = *src; /*k+1 write, src,dst,offset point to current pos should be written */
+
+ flashptr[0] = 0x29; /* program to flash confirm */
+ //udelay(5);
+#if 1
+ do {
+ d1 = flashptr[offset/2]; /* read data */
+ if ((d1 & 0x80) == (*src & 0x80)) { /* check DQ7 ok */
+ stat = STATUS_READY;
+ goto next;
+ }
+ i++;
+ } while ( ((d1 & 0x20)!=0x20) && ((d1 & 0x02)!=0x02) );
+
+ d1 = flashptr[offset/2]; /* read data */
+ if ((d1 & 0x80) != (*src & 0x80)) /* check DQ7 ok */
+ {
+ printk("CHECK Time_Out\n");
+ stat = STATUS_TIMEOUT;
+ break;
+ }
+ else stat = STATUS_READY;
+#else
+ do {
+ d1 = *flashptr; /* read data */
+ d2 = d1 ^ *flashptr; /* read it again and see what toggled */
+ if (d2 == 0) { /* no toggles, nothing's happening */
+ stat = STATUS_READY;
+ goto next;
+ }
+ } while (!(d2 & 0x20));
+
+ d1 = *flashptr; /* read data */
+ d2 = d1 ^ *flashptr; /* read it again and see what toggled */
+ if (d2 != 0) {
+ stat=STATUS_TIMEOUT;
+ break;
+ }
+#endif
+next:
+ dst++; /* next batch start to write */
+ src++; /* next batch start to read */
+ nbytes -= 32;
+ offset += 2 ;
+ }
+
+ if (stat != STATUS_READY || nbytes > 0) {
+ UINT16 data;
+ data = flashptr[offset/2];
+ if ((data & 0x02) == 0x02) {
+ flashptr[0x555] = 0xaa;
+ flashptr[0x2aa] = 0x55;
+ flashptr[0x555] = 0xf0;
+ printk("abort to write to buffer @ 0x%lx =0x%x\n", offset,data);
+ }
+ else {
+ cfi_flash_command(FLASH_RESET,sector,0,0);
+ printk("fail to write to buffer @ 0x%lx =0x%x\n", offset,data);
+ }
+ }
+ else { cfi_flash_command(FLASH_RESET,sector,0,0);}
+
+
+
+ }
+else {
cfi_flash_command(FLASH_UB, 0, 0, 0);
while (nbytes > 0) {
+
+ //swda add,06/27/2006
+ if ( (nbytes%1024) == 0 ) {
+ DiagLedBlinking();
+ }
+ //swda add end
+
cfi_flash_command(FLASH_PROG, sector, offset, *src);
if (cfi_flash_wait(sector, offset, *src) != STATUS_READY)
break;
src++;
}
cfi_flash_command(FLASH_UBRESET, 0, 0, 0);
-
+}
return (unsigned char*)src - buf;
}
{
volatile unsigned short *flashptr; /* flash window */
unsigned short d1;
+ int i1 = 0;//swda add,06/27/2006
flashptr = (unsigned short *) cfi_flash_get_memptr(sector);
d1 = flashptr[offset/2];
if (d1 == data)
return STATUS_READY;
+ //swda add,06/27/2006
+ i1++;
+ if ( (i1%1024) == 0 ) {
+ DiagLedBlinking();
+ i1 = 0;
+ }
+ //swda add end
} while (!(d1 & 0x20));
d1 = flashptr[offset/2];
if (d1 == data)
return STATUS_READY;
CFI_USLEEP(10);
+ //swda add,06/27/2006
+ if ( (i%1024) == 0 ) {
+ DiagLedBlinking();
+ }
+ //swda add end
}
d1 = flashptr[offset/2];
d1 ^= *flashptr; /* read it again and see what toggled */
if (d1 == 0) /* no toggles, nothing's happening */
return STATUS_READY;
+ //swda add,06/27/2006
+ i1++;
+ if ( (i1%1024) == 0 ) {
+ DiagLedBlinking();
+ i1 = 0;
+ }
+ //swda add end
} while (!(d1 & 0x20));
d1 = *flashptr; /* read data */
#endif
} else if (flashFamily == FLASH_INTEL) {
flashptr[0] = 0x70;
+#if 0 //swda modify,06/27/2006
/* Wait for completion */
while(!(*flashptr & 0x80));
+#else
+ while(!(*flashptr & 0x80)) {
+ i1++;
+ if ( (i1%1024) == 0 ) {
+ DiagLedBlinking();
+ i1 = 0;
+ }
+ }
+#endif //swda modify end
if (*flashptr & 0x30) {
flashptr[0] = 0x50;
cfi_flash_command(FLASH_RESET, 0, 0, 0);
fwp = (unsigned short *) cfi_flash_get_memptr(0);
cfi_flash_command(FLASH_READ_ID, 0, 0, 0);
+ man_id = *(fwp);
answer = *(fwp + 1);
if (answer == ID_AM29LV320M) {
answer = *(fwp + 0xe);
return(FLASH_API_OK);
}
+//swda add,06/27/2006
+static int DiagLedBlinking(void)
+{
+ static int diag_led = 0;
+ static int curr_time = 0;
+ static int prev_time = 0;
+ static int UpgradeState = 0;
+ static int blink_interval = T200ms;
+
+ UpgradeState = kerSysGetUpgradeState();
+ if ( !UpgradeState )
+ return 0;//not update image or not update configuration, so do nothing
+
+ if ( UpgradeState == 2 ) { //update configuration
+ blink_interval = T100ms;
+ } else { //update image
+ blink_interval = T200ms;
+ }
+ curr_time = jiffies;
+ if ( (curr_time - prev_time) >= blink_interval ) {
+ prev_time = curr_time;
+ if (diag_led) {
+ kerSysLedCtrl(kLedDiag, kLedStateOff);
+ diag_led = 0;
+ } else {
+ kerSysLedCtrl(kLedDiag, kLedStateOn);
+ diag_led = 1;
+ }
+ }
+ return 0;
+}
+//swda add end