/******************************************************************************* * mvFlashInit - Initialize a flash descriptor structure. * * DESCRIPTION: * This function intialize flash info struct with specified flash * parameters. This structure is used to identify the target flash the * function refers to. This allow the use of the same API for multiple * flash devices. * * * INPUT: * pFlash->baseAddr - Flash base address. * pFlash->busWidth - Flash bus width (8, 16, 32 bit). * pFlash->devWidth - Flash device width (8 or 16 bit). * * OUTPUT: * pFlash - Flash identifier structure. * * RETURN: * 32bit describing flash size. * In case of any error, it returns 0. * *******************************************************************************/ MV_U32 mvFlashInit(MV_FLASH_INFO *pFlash) { MV_U32 manu = 0, id = 0; if(NULL == pFlash) return 0; DB(mvOsPrintf("Flash: mvFlashInit base 0x%x devW %d busW %d\n", pFlash->baseAddr, pFlash->devWidth, pFlash->busWidth)); /* must init first sector base, before calling flashCmdSet */ pFlash->sector[0].baseOffs = 0; /* reset flash 0xf0(AMD) 0xff (Intel) */ flashCmdSet(pFlash, 0, 0, 0xf0); flashCmdSet(pFlash, 0, 0, 0xff); /* Write auto select command: read Manufacturer ID */ /* AMD seq is: 0x555 0xAA -> 0x2AA 0x55 -> 0x555 0x90 */ /* INTEL seq is dc 0x90 */ flashCmdSet(pFlash, 0x555, 0, 0xAA); flashCmdSet(pFlash, 0x2AA, 0, 0x55); flashCmdSet(pFlash, 0x555, 0, 0x90); /* get flash Manufactor and Id */ manu = flashBusWidthRd(pFlash, mvFlashBaseAddrGet(pFlash)); id = flashBusWidthRd(pFlash, flashAddrExt(pFlash, 1, 0)); /* check if this flash is Supported, and Init the pFlash flash feild */ if( MV_OK != flashStructGet(pFlash, manu, id ) ) { mvOsPrintf("%s: Flash ISN'T supported: manufactor-0x%x, id-0x%x\n", __FUNCTION__, manu, id); return 0; } /* Init pFlash sectors */ if(MV_OK != flashSecsInit(pFlash)) { mvOsPrintf("Flash: ERROR mvFlashInit flashSecsInit failed \n"); return 0; } /* print all flash information */ DB(flashPrint(pFlash)); /* reset the Flash */ flashReset(pFlash); return mvFlashSizeGet(pFlash); }
/****************************************************************************** * flashAddrExt - Extend Addr. * DESCRIPTION: * Should be used only for FLASH CFI command sequence. * * Prepare the Addr according to the Flash width and the bus width, * and add the sector offset. * If flash width = 2 and bus width = 1 then it means we are using 16 Bit * flash in 8 Bit mode, we should make sure that we shift the addr in 1 bit * since in 16 Bit flash A0 isn't connected. and A1 of the MV dev address will * go to A1 of the Flash. * If flash width = 2 and bus width = 4 then it means we are using 2 16 Bit * flash, (for the 16 Bit flash A0 isn't connected) and since when we refer to * address 0x4 we actually want to refer to 0x2 of each device, then we will * connect A2 of the MV Dev addres to A1 of the flash. * * INPUT: * addr - Addr to be expended. * pFlash - flash information. * secNum - Sector Number. * * OUTPUT: * None * * RETURN: * MV_U32 - Data after extension. * 0 if pFlash is Null. * *******************************************************************************/ MV_U32 flashAddrExt(MV_FLASH_INFO *pFlash, MV_U32 addr, MV_U32 secNum ) { MV_U32 shift; if(NULL == pFlash) return 0; shift = (pFlash->busWidth > pFlash->devWidth ) ? pFlash->busWidth : pFlash->devWidth; addr = addr * shift; /* Add flash sector Offset.*/ addr += (mvFlashSecOffsGet(pFlash,secNum) + mvFlashBaseAddrGet(pFlash)); return addr; }
/******************************************************************************* * flashPrint - Print flash information structure. * * DESCRIPTION: * Prints all the feilds in the flash info structure. * * INPUT: * pFlash - Flash information. * * OUTPUT: * None * * RETURN: * None * *******************************************************************************/ MV_VOID flashPrint(MV_FLASH_INFO *pFlash) { MV_U32 i; if ((NULL == pFlash) || (mvFlashVenIdGet(pFlash) == 0)) { mvOsOutput ("missing or unknown FLASH type\n"); return; } switch (mvFlashVenIdGet(pFlash)) { case STM_MANUF: mvOsOutput ("STM "); break; case AMD_MANUF: mvOsOutput ("AMD "); break; case FUJ_MANUF: mvOsOutput ("FUJITSU "); break; case INTEL_MANUF: mvOsOutput ("INTEL "); break; case SST_MANUF: mvOsOutput ("SST "); break; case MX_MANUF: mvOsOutput ("MX "); break; default: mvOsOutput ("Unknown Vendor 0x%x",mvFlashVenIdGet(pFlash)); break; } switch (mvFlashDevIdGet(pFlash)) { case AMD_FID_LV040B: mvOsOutput ("AM29LV040B (4 Mbit, bottom boot sect)"); break; case AMD_FID_LV400B: mvOsOutput ("AM29LV400B (4 Mbit, bottom boot sect)"); break; case AMD_FID_LV400T: mvOsOutput ("AM29LV400T (4 Mbit, top boot sector)"); break; case AMD_FID_LV800B: mvOsOutput ("AM29LV800B (8 Mbit, bottom boot sect)"); break; case AMD_FID_LV800T: mvOsOutput ("AM29LV800T (8 Mbit, top boot sector)"); break; case AMD_FID_LV160B: mvOsOutput ("AM29LV160B (16 Mbit, bottom boot sect)"); break; case AMD_FID_LV160T: mvOsOutput ("AM29LV160T (16 Mbit, top boot sector)"); break; case AMD_FID_LV320B: mvOsOutput ("AM29LV320B (32 Mbit, bottom boot sect)"); break; case AMD_FID_LV320T: mvOsOutput ("AM29LV320T (32 Mbit, top boot sector)"); break; case STM_FID_29W040B: mvOsOutput ("M29W040B (4Mbit = 512K x 8) "); break; case INTEL_FID_28F320J3A: mvOsOutput ("28F320J3A (32 Mbit)"); break; case INTEL_FID_28F640J3A: mvOsOutput ("28F640J3A (64 Mbit)"); break; case INTEL_FID_28F128J3A: mvOsOutput ("28F128J3A (128 Mbit)"); break; case INTEL_FID_28F128P30T: mvOsOutput ("28F128P30 TOP (128 Mbit)"); break; case INTEL_FID_28F128P30B: mvOsOutput ("28F128P30 BOTTOM (128 Mbit)"); break; case INTEL_FID_28F256P30T: mvOsOutput ("28F256P30 TOP (256 Mbit)"); break; #if defined (DB_88F1281) case INTEL_FID_28F256P30B: mvOsOutput ("28F256P30 BOTTOM (128 Mbit)"); break; #else case INTEL_FID_28F256P30B: mvOsOutput ("28F256P30 BOTTOM (256 Mbit)"); break; #endif case SST_39VF_020: mvOsOutput ("SST39VF020 (2 Mbit)"); break; default: mvOsOutput ("Unknown Chip Type id 0x%x",mvFlashDevIdGet(pFlash)); break; } if(mvFlashNumOfDevGet(pFlash) > 1) mvOsOutput(" X %d",mvFlashNumOfDevGet(pFlash)); mvOsOutput("\nSize: "); sizePrint(mvFlashSizeGet(pFlash)," in "); mvOsOutput("%d Sectors\n",mvFlashNumOfSecsGet(pFlash)); mvOsOutput("Bus Width: %dbit, device Width: %dbit, type: ", (8 * mvFlashBusWidthGet(pFlash)), (8 * mvFlashDevWidthGet(pFlash))); switch (mvFlashSecTypeGet(pFlash)) { case TOP: mvOsOutput ("TOP"); break; case BOTTOM: mvOsOutput ("BOTTOM"); break; case REGULAR: mvOsOutput ("REGULAR"); break; default: mvOsOutput ("Unknown Type"); break; } mvOsOutput(".\n"); mvOsOutput (" Sector Start Addresses:"); for (i=0; i<mvFlashNumOfSecsGet(pFlash); ++i) { if ((i % 5) == 0) mvOsOutput ("\n "); mvOsOutput (" %08lX%s", (mvFlashSecOffsGet(pFlash, i) + mvFlashBaseAddrGet(pFlash)), mvFlashSecLockGet(pFlash,i) ? " (RO)" : " " ); } mvOsOutput("\n"); return; }
/******************************************************************************* * mvFlashInit - Initialize a flash descriptor structure. * * DESCRIPTION: * This function intialize flash info struct with specified flash * parameters. This structure is used to identify the target flash the * function refers to. This allow the use of the same API for multiple * flash devices. * * * INPUT: * pFlash->baseAddr - Flash base address. * pFlash->busWidth - Flash bus width (8, 16, 32 bit). * pFlash->devWidth - Flash device width (8 or 16 bit). * * OUTPUT: * pFlash - Flash identifier structure. * * RETURN: * 32bit describing flash size. * In case of any error, it returns 0. * *******************************************************************************/ MV_U32 mvFlashInit(MV_FLASH_INFO *pFlash) { MV_U32 manu = 0, id = 0; if(NULL == pFlash) return 0; DB(mvOsOutput("Flash: mvFlashInit base 0x%x devW %d busW %d\n", pFlash->baseAddr, pFlash->devWidth, pFlash->busWidth)); /* must init first sector base, before calling flashCmdSet */ pFlash->sector[0].baseOffs = 0; /* reset flash 0xf0(AMD) 0xff (Intel) */ flashCmdSet(pFlash, 0, 0, 0xf0); flashCmdSet(pFlash, 0, 0, 0xff); /* Write auto select command: read Manufacturer ID */ /* AMD seq is: 0x555 0xAA -> 0x2AA 0x55 -> 0x555 0x90 */ /* INTEL seq is dc 0x90 */ flashCmdSet(pFlash, 0x555, 0, 0xAA); flashCmdSet(pFlash, 0x2AA, 0, 0x55); flashCmdSet(pFlash, 0x555, 0, 0x90); /* Write auto select command: read Manufacturer ID */ /* SST seq is: 0x5555 0xAA -> 0x2AAA 0x55 -> 0x5555 0x90 */ flashCmdSet(pFlash, 0x5555, 0, 0xAA); flashCmdSet(pFlash, 0x2AAA, 0, 0x55); flashCmdSet(pFlash, 0x5555, 0, 0x90); DB(mvOsOutput("Flash: mvFlashInit base 0x%x devW %d busW %d\n", pFlash->baseAddr, pFlash->devWidth, pFlash->busWidth)); /* get flash Manufactor and Id */ manu = flashBusWidthRd(pFlash, mvFlashBaseAddrGet(pFlash)); DB(mvOsOutput("Flash: mvFlashInit base 0x%x devW %d busW %d\n", pFlash->baseAddr, pFlash->devWidth, pFlash->busWidth)); /* Some Micron flashes don't use A0 address for Identifier and Lock information, so in order to read Identifier and lock information properly we will do the following workarround: If our device width is 1 (x8) then if address 0 equal to address 1 and address 2 equal to address 3 ,then we have this case (A0 is not used) and then we will issue the address without A0 to read the Identifier and lock information properly*/ DB(mvOsOutput("Flash: mvFlashInit base 0x%x devW %d busW %d\n", pFlash->baseAddr, pFlash->devWidth, pFlash->busWidth)); if ((pFlash->devWidth == 1) && ((flashBusWidthRd(pFlash, flashAddrExt(pFlash, 0, 0)) == flashBusWidthRd(pFlash, flashAddrExt(pFlash, 1, 0)))&& (flashBusWidthRd(pFlash, flashAddrExt(pFlash, 2, 0)) == flashBusWidthRd(pFlash, flashAddrExt(pFlash, 3, 0))))) { id = flashBusWidthRd(pFlash, flashAddrExt(pFlash, 2, 0)); } else id = flashBusWidthRd(pFlash, flashAddrExt(pFlash, 1, 0)); /* check if this flash is Supported, and Init the pFlash flash feild */ if( MV_OK != flashStructGet(pFlash, manu, id ) ) { mvOsPrintf("%s: Flash ISN'T supported: manufactor-0x%x, id-0x%x\n", __FUNCTION__, manu, id); return 0; } DB(mvOsOutput("Flash: mvFlashInit base 0x%x devW %d busW %d\n", pFlash->baseAddr, pFlash->devWidth, pFlash->busWidth)); /* Init pFlash sectors */ if(MV_OK != flashSecsInit(pFlash)) { mvOsPrintf("Flash: ERROR mvFlashInit flashSecsInit failed \n"); return 0; } DB(mvOsOutput("Flash: mvFlashInit base 0x%x devW %d busW %d\n", pFlash->baseAddr, pFlash->devWidth, pFlash->busWidth)); /* print all flash information */ DB(flashPrint(pFlash)); /* reset the Flash */ flashReset(pFlash); DB(mvOsOutput("Flash: mvFlashInit base 0x%x devW %d busW %d\n", pFlash->baseAddr, pFlash->devWidth, pFlash->busWidth)); return mvFlashSizeGet(pFlash); }