/******************************************************************************* * 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); }
/******************************************************************************* * flashCmdSet - Write converted data to the flash converted address+sector base. * * DESCRIPTION: * Convert data based on the bus width and the flash device width * and write it to secoffset + converted address. * Should be used only for FLASH command sequence. * * INPUT: * addr - Address offset. * secNum - In which sector the address is sitting. * data - Data to be written. * pFlash - flash information. * * OUTPUT: * None * * RETURN: * None * *******************************************************************************/ MV_VOID flashCmdSet(MV_FLASH_INFO *pFlash, MV_U32 addr, MV_U32 secNum, MV_U32 data) { if(NULL == pFlash) return; /* prepare the Data according to the Flash Width and Bus Width. */ data = flashDataExt(pFlash, data); addr = flashAddrExt(pFlash, addr, secNum); flashBusWidthWr(pFlash,addr,data); 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); }