xilflash_v4_1: Fix Spansion write buffer programming.

This patch fixes the spansion write buffer programming
issue.

Signed-off-by: naga sureshkumar relli <nagasure@xilinx.com>
This commit is contained in:
naga sureshkumar relli 2015-06-09 11:24:04 +05:30 committed by Nava kishore Manne
parent 6c21998270
commit cc85685a73
3 changed files with 362 additions and 101 deletions

View file

@ -204,6 +204,9 @@
* Description: Non-word aligned data write to flash fails
* with AXI interface.
* 3.04a srt 02/18/13 Fixed CR 700553.
* 4.1 nsk 06/06/12 Updated WriteBuffer programming for spansion
* in xilflash_amd.c and added new definitions
* as per AMD Spec in xilflash_amd.h (CR 781697).
*
* </pre>
*

View file

@ -46,6 +46,8 @@
* 2.01a ktn 03/31/10 Updated the AMD code to support uniform sector WP modes.
* Addded the new definitions XFL_AMD_TOP_WP_UNIFORM and
* XFL_AMD_BOTTOM_WP_UNIFORM.
* 4.1 nsk 06/06/12 Added New definitions as per AMD spec.
* (CR 781697).
* </pre>
*
******************************************************************************/
@ -89,6 +91,9 @@ extern "C" {
#define XFL_AMD_CMD_ERASE_BLOCK (0x0030) /* Erase 2 command */
#define XFL_AMD_CMD_UNLOCK_BYPASS (0x0020) /* Unlock bypass command */
#define XFL_AMD_CMD_PROGRAM (0x00A0) /* Program command */
#define XFL_AMD_CMD_WRITE_BUFFER (0x0025) /* Write to Buffer command */
#define XFL_AMD_CMD_PROGRAM_BUFFER (0x0029) /* Program Buffer to Flash
command */
#define XFL_AMD_CMD_UNLOCK_BYPASS_RESET1 (0x0090) /* Unlock bypass 1 command */
#define XFL_AMD_CMD_UNLOCK_BYPASS_RESET2 (0x0000) /* Unlock bypass 1 command */
#define XFL_AMD_CMD_ERASE_CHIP (0x0010) /* Chip erase command */
@ -96,6 +101,23 @@ extern "C" {
#define XFL_AMD_CMD_EXIT_EXT_MODE (0x0090) /* Enter extended mode */
#define XFL_AMD_CMD_GROUP_PROTECT1 (0x0060) /* Group protect command */
#define XFL_AMD_CMD_GROUP_PROTECT2 (0x0040) /* Group protect command */
#define XFL_AMD_CMD_STATUS_REG_READ (0x0070) /* Status Register Read
Command */
#define XFL_AMD_CMD_STATUS_REG_CLEAR (0x0071) /* Status Register Clear Command
*/
/*
* The following constant defines Status Register Bits.
*/
#define XFL_AMD_DEVICE_READY_MASK 0x80 /* Device Ready */
#define XFL_AMD_DEVICE_ERASE_INSUSPEND_MASK 0x40 /* Erase in suspend */
#define XFL_AMD_DEVICE_ERASE_FAIL_MASK 0x20 /* Erase in Fail */
#define XFL_AMD_DEVICE_PROGRAM_FAIL_MASK 0x10 /* Program Write Fail */
#define XFL_AMD_DEVICE_PROGRAM_ABORT_MASK 0x08 /* Program aborted */
#define XFL_AMD_DEVICE_PROGRAM_SUSPEND_MASK 0x04 /* Program in Suspend */
#define XFL_AMD_DEVICE_SECTOR_LOCKED_ERR_MASK 0x02 /* Sector was locked */
#define XFL_AMD_DEVICE_STATUS_REG_MASK 0xFF /* Status Register Mask
*/
/*
* The following constant defines command set of AMD flash family.

View file

@ -78,6 +78,8 @@
* 2.02a sdm 07/07/10 Updated XFlashAmd_Initialize() to NOT change the erase
* region information of a top boot device, when the number
* of erase regions is not more than 1.
* 4.1 nsk 06/06/12 Updated Spansion WriteBuffer programming.
* (CR 781697).
* </pre>
*
******************************************************************************/
@ -189,9 +191,48 @@ extern int XFlashGeometry_ToAbsolute(XFlashGeometry * InstancePtr,
u16 Region,
u16 Block,
u32 BlockOffset, u32 *AbsoluteOffsetPtr);
int WriteSingleBuffer(XFlash * InstancePtr, void *DestPtr,
void *SrcPtr, u32 Bytes);
static int WriteBufferAmd(XFlash * InstancePtr, void *DestPtr,
void *SrcPtr, u32 Bytes);
static int WriteBufferSpansion(XFlash * InstancePtr, void *DestPtr,
void *SrcPtr, u32 Bytes);
void AmdDevice_is_Ready(XFlash * InstancePtr);
/************************** Variable Definitions *****************************/
/*****************************************************************************/
/**
*
* Check the device is ready or not.
*
* @param InstancePtr is a pointer to the XFlash instance.
*
* @return
* This API waits until the device ready.
*
* @note None.
*
******************************************************************************/
void AmdDevice_is_Ready(XFlash * InstancePtr)
{
u32 FlashStatus;
XFlashGeometry *GeomPtr;
GeomPtr = &InstancePtr->Geometry;
XFlashVendorData_Amd *DevDataPtr;
DevDataPtr = GET_PARTDATA(InstancePtr);
while (1) {
/* Send Status Register Read Command. */
DevDataPtr->SendCmd(GeomPtr->BaseAddress,XFL_AMD_CMD1_ADDR,
XFL_AMD_CMD_STATUS_REG_READ);
FlashStatus = DevDataPtr->GetStatus(GeomPtr->BaseAddress,0);
if (FlashStatus & XFL_AMD_DEVICE_READY_MASK)
break;
}
}
/*****************************************************************************/
/**
*
@ -425,10 +466,13 @@ int XFlashAmd_Read(XFlash *InstancePtr, u32 Offset, u32 Bytes, void *DestPtr)
u16 *Src16BitPtr;
u32 PartMode;
u32 Index;
u32 Startoffset;
u32 EndOffset;
XFlashGeometry *GeomPtr;
XFlashVendorData_Amd *DevDataPtr;
volatile u16 FlashStatus;
/*
* Verify inputs are valid.
*/
/* Verify inputs are valid. */
if(InstancePtr == NULL) {
return (XST_FAILURE);
}
@ -441,20 +485,33 @@ int XFlashAmd_Read(XFlash *InstancePtr, u32 Offset, u32 Bytes, void *DestPtr)
return (XST_FAILURE);
}
GeomPtr = &InstancePtr->Geometry;
DevDataPtr = GET_PARTDATA(InstancePtr);
if (InstancePtr->Geometry.MemoryLayout == XFL_LAYOUT_X16_X16_X1) {
Startoffset = Offset >> 1;
EndOffset = Offset + Bytes - 1;
EndOffset = EndOffset >> 1;
}
else {
Startoffset = Offset;
}
PartMode = (InstancePtr->Geometry.MemoryLayout &
XFL_LAYOUT_PART_MODE_MASK);
/*
* Check to make sure start address is within the device.
*/
if (!XFL_GEOMETRY_IS_ABSOLUTE_VALID(&InstancePtr->Geometry, Offset)) {
if (!XFL_GEOMETRY_IS_ABSOLUTE_VALID(&InstancePtr->Geometry,
Startoffset)) {
return (XFLASH_ADDRESS_ERROR);
}
/*
* Reset the bank(s) so that it returns to the read mode.
*/
if (XFlashAmd_ResetBank(InstancePtr, Offset, Bytes) != XST_SUCCESS) {
if (XFlashAmd_ResetBank(InstancePtr, Startoffset, Bytes)
!= XST_SUCCESS) {
return (XST_FAILURE);
}
@ -475,18 +532,21 @@ int XFlashAmd_Read(XFlash *InstancePtr, u32 Offset, u32 Bytes, void *DestPtr)
}
else if (PartMode == XFL_LAYOUT_PART_MODE_16) {
/*
* Perform copy to the user buffer from the buffer.
*/
Src16BitPtr = (u16*) (((volatile u16*) InstancePtr->Geometry.
BaseAddress) + Offset);
Dest16BitPtr = (u16*) DestPtr;
/* Wait until device is ready. */
AmdDevice_is_Ready(InstancePtr);
/* Send Status Register Clear Command. */
DevDataPtr->SendCmd(GeomPtr->BaseAddress,XFL_AMD_CMD1_ADDR,
XFL_AMD_CMD_STATUS_REG_CLEAR);
/* Perform copy to the user buffer from the buffer. */
Src16BitPtr = (u16*) (((volatile u16*) InstancePtr->Geometry.
BaseAddress) + Startoffset);
Dest16BitPtr = (u16*) DestPtr;
for (Index = 0; Index < (Bytes/2); Index++) {
Dest16BitPtr[Index] = Src16BitPtr[Index];
}
}
else {
} else {
return (XFLASH_PART_NOT_SUPPORTED);
}
@ -519,11 +579,11 @@ int XFlashAmd_Read(XFlash *InstancePtr, u32 Offset, u32 Bytes, void *DestPtr)
int XFlashAmd_Write(XFlash * InstancePtr, u32 Offset, u32 Bytes, void *SrcPtr)
{
int Status;
u32 StartOffset;
u32 EndOffset;
XFlashVendorData_Amd *DevDataPtr;
/*
* Verify inputs are valid.
*/
/* Verify inputs are valid. */
if(InstancePtr == NULL) {
return (XST_FAILURE);
}
@ -532,32 +592,34 @@ int XFlashAmd_Write(XFlash * InstancePtr, u32 Offset, u32 Bytes, void *SrcPtr)
return (XST_FAILURE);
}
/*
* Nothing specified to be programmed.
*/
/* Nothing specified to be programmed. */
if (Bytes == 0) {
return (XST_SUCCESS);
}
/*
* Verify the address range is within the part.
*/
if (!XFL_GEOMETRY_IS_ABSOLUTE_VALID(&InstancePtr->Geometry, Offset) ||
!XFL_GEOMETRY_IS_ABSOLUTE_VALID(&InstancePtr->Geometry,
Offset + Bytes - 1)) {
if (InstancePtr->Geometry.MemoryLayout == XFL_LAYOUT_X16_X16_X1){
StartOffset = Offset >> 1;
EndOffset = Offset + Bytes -1;
EndOffset = EndOffset >> 1;
}
else {
StartOffset = Offset ;
EndOffset = Offset + Bytes -1;
}
/* Verify the address range is within the part. */
if (!XFL_GEOMETRY_IS_ABSOLUTE_VALID(&InstancePtr->Geometry, StartOffset)
|| !XFL_GEOMETRY_IS_ABSOLUTE_VALID(&InstancePtr->Geometry,
EndOffset)) {
return (XFLASH_ADDRESS_ERROR);
}
/*
* Call the proper write buffer function.
*/
/* Call the proper write buffer function. */
DevDataPtr = GET_PARTDATA(InstancePtr);
Status = DevDataPtr->WriteBuffer(InstancePtr, (void *)Offset, SrcPtr,
Bytes);
(Bytes));
/*
* Reset the bank(s) so that it returns to the read mode.
*/
/* Reset the bank(s) so that it returns to the read mode. */
(void) XFlashAmd_ResetBank(InstancePtr, Offset, Bytes);
return (Status);
@ -593,31 +655,38 @@ int XFlashAmd_Erase(XFlash * InstancePtr, u32 Offset, u32 Bytes)
u16 BlocksLeft;
u16 BlocksQueued;
u32 Dummy;
u32 StartOffset;
u32 EndOffset;
int Status;
XFlashGeometry *GeomPtr;
XFlashVendorData_Amd *DevDataPtr;
/*
* Verify inputs are valid.
*/
if(InstancePtr == NULL) {
/* Verify inputs are valid. */
if (InstancePtr == NULL) {
return (XST_FAILURE);
}
GeomPtr = &InstancePtr->Geometry;
/*
* Handle case when zero bytes is provided.
*/
/* Handle case when zero bytes is provided. */
if (Bytes == 0) {
return (XST_SUCCESS);
}
if (InstancePtr->Geometry.MemoryLayout == XFL_LAYOUT_X16_X16_X1) {
StartOffset = Offset >> 1;
EndOffset = Offset + Bytes - 1;
EndOffset = EndOffset >> 1;
}
else {
StartOffset = Offset;
EndOffset = Offset + Bytes - 1;
}
/*
* Convert the starting address to block coordinates. This also verifies
* the starting address is within the instance's address space.
*/
Status = XFlashGeometry_ToBlock(GeomPtr, Offset, &StartRegion,
Status = XFlashGeometry_ToBlock(GeomPtr, StartOffset, &StartRegion,
&StartBlock, &Dummy);
if (Status != XST_SUCCESS) {
return (XFLASH_ADDRESS_ERROR);
@ -627,8 +696,8 @@ int XFlashAmd_Erase(XFlash * InstancePtr, u32 Offset, u32 Bytes)
* Convert the ending address to block coordinates. This also verifies
* the ending address is within the instance's address space.
*/
Status = XFlashGeometry_ToBlock(GeomPtr, Offset + Bytes - 1, &
EndRegion, &EndBlock, &Dummy);
Status = XFlashGeometry_ToBlock(GeomPtr, EndOffset,
&EndRegion, &EndBlock, &Dummy);
if (Status != XST_SUCCESS) {
return (XFLASH_ADDRESS_ERROR);
}
@ -644,17 +713,16 @@ int XFlashAmd_Erase(XFlash * InstancePtr, u32 Offset, u32 Bytes)
BlocksQueued = EnqueueEraseBlocks(InstancePtr, &StartRegion,
&StartBlock, BlocksLeft);
BlocksLeft -= BlocksQueued;
Status = DevDataPtr->PollSR(GeomPtr->BaseAddress, Offset);
Status = DevDataPtr->PollSR(GeomPtr->BaseAddress, StartOffset);
if (Status != XFLASH_READY) {
(void) XFlashAmd_ResetBank(InstancePtr, Offset, Bytes);
(void) XFlashAmd_ResetBank(InstancePtr, StartOffset,
Bytes);
return (Status);
}
}
/*
* Reset the bank(s) so that it returns to the read mode.
*/
(void) XFlashAmd_ResetBank(InstancePtr, Offset, Bytes);
/* Reset the bank(s) so that it returns to the read mode. */
(void) XFlashAmd_ResetBank(InstancePtr, StartOffset, Bytes);
return (XST_SUCCESS);
}
@ -1153,13 +1221,9 @@ static int XFlashAmd_ResetBank(XFlash * InstancePtr, u32 Offset, u32 Bytes)
(Offset + Bytes - 1)) &&
(Region < InstancePtr->Geometry.NumEraseRegions)) {
/*
* Send the clear status register command. Use the max write
* Send the Command Reset. Use the max write
* width to notify parts of all layouts.
*/
DevDataPtr->SendCmdSeq(InstancePtr->Geometry.BaseAddress,
XFL_AMD_CMD1_ADDR, XFL_AMD_CMD2_ADDR,
XFL_AMD_CMD1_DATA, XFL_AMD_CMD2_DATA);
DevDataPtr->WriteFlash(InstancePtr->Geometry.BaseAddress,
InstancePtr->Geometry.EraseRegion
[Region].AbsoluteOffset,
@ -1555,19 +1619,116 @@ static int WriteBuffer8(XFlash * InstancePtr, void *DestPtr,
static int WriteBuffer16(XFlash * InstancePtr, void *DestPtr,
void *SrcPtr, u32 Bytes)
{
u16 *SourcePtr = (u16*)SrcPtr;
u32 DestinationPtr = (u32)DestPtr;
u32 BaseAddress;
u32 Index = 0;
int Status = XST_SUCCESS;
XFlashVendorData_Amd *DevDataPtr;
DevDataPtr = GET_PARTDATA(InstancePtr);
BaseAddress = InstancePtr->Geometry.BaseAddress;
u32 Status;
u16 *SrcWordPtr = (u16*)SrcPtr;
u16 *DestWordPtr = (u16*)DestPtr;
/*
* Send the Unlock Bypass command.
* Make sure DestPtr and SrcPtr are aligned to a 16-bit word.
*/
if (((int) SrcWordPtr & 1) || ((int) DestWordPtr & 1)) {
return (XFLASH_ALIGNMENT_ERROR);
}
if (InstancePtr->Properties.PartID.ManufacturerID == 0x01)
Status = WriteBufferSpansion(InstancePtr,DestPtr,SrcPtr,Bytes);
else
Status = WriteBufferAmd(InstancePtr,DestPtr,SrcPtr,Bytes);
return Status;
}
/*****************************************************************************/
/**
*
* This function is used to program Spansion devices. It does not erase
* the flash first and will fail if the block(s) are not erased first. The
* device(s) are programmed in parallel.
*
* @param InstancePtr is the instance to work on.
* @param DestPtr is the physical destination address in flash memory
* space.
* @param SrcPtr is the source data.
* @param Bytes is the number of bytes to program.
*
* @return
* - XST_SUCCESS if successful.
* - XFLASH_ERROR if a write error occurred. This error is
* usually device specific.
*
* @note None.
*
******************************************************************************/
static int WriteBufferSpansion(XFlash * InstancePtr, void *DestPtr,
void *SrcPtr, u32 Bytes)
{
u32 DestinationPtr = (u32)DestPtr;
u32 BaseAddress= InstancePtr->Geometry.BaseAddress;
u16* Tempsrcptr = (u16 *)SrcPtr;
u32 Index = 0;
int Status = XST_SUCCESS;
XFlashVendorData_Amd *DevDataPtr = GET_PARTDATA(InstancePtr);
u32 BufferSize = InstancePtr->Properties.ProgCap.WriteBufferSize;
while (Bytes != NULL)
{
/* Bytes to write should not exceed the buffer size. */
if (Bytes > BufferSize)
{
Status = WriteSingleBuffer(InstancePtr, DestPtr,
Tempsrcptr, BufferSize);
Bytes = Bytes - BufferSize;
DestPtr = DestPtr + BufferSize;
Tempsrcptr = Tempsrcptr + BufferSize/2;
}
else
{
Status = WriteSingleBuffer(InstancePtr, DestPtr,
Tempsrcptr, Bytes);
Bytes = 0;
}
if (Status != XST_SUCCESS)
{
return Status;
}
}
return Status;
}
/*****************************************************************************/
/**
*
* This function is used to program Amd devices. It does not erase
* the flash first and will fail if the block(s) are not erased first. The
* device(s) are programmed in parallel.
*
* @param InstancePtr is the instance to work on.
* @param DestPtr is the physical destination address in flash memory
* space.
* @param SrcPtr is the source data.
* @param Bytes is the number of bytes to program.
*
* @return
* - XST_SUCCESS if successful.
* - XFLASH_ERROR if a write error occurred. This error is
* usually device specific.
*
* @note None.
*
******************************************************************************/
static int WriteBufferAmd(XFlash * InstancePtr, void *DestPtr,
void *SrcPtr, u32 Bytes)
{
u16 *SourcePtr = (u16*)SrcPtr;
u32 DestinationPtr = (u32)DestPtr;
u32 BaseAddress = InstancePtr->Geometry.BaseAddress;
u32 Index = 0;
int Status = XST_SUCCESS;
XFlashVendorData_Amd *DevDataPtr = GET_PARTDATA(InstancePtr);
/* Send the Unlock Bypass command. */
DevDataPtr->SendCmdSeq(BaseAddress,
XFL_AMD_CMD1_ADDR, XFL_AMD_CMD2_ADDR,
XFL_AMD_CMD1_DATA, XFL_AMD_CMD2_DATA);
@ -1596,9 +1757,7 @@ static int WriteBuffer16(XFlash * InstancePtr, void *DestPtr,
Bytes -= 2;
}
/*
* Unlock Bypass Reset.
*/
/* Unlock Bypass Reset. */
DevDataPtr->WriteFlash(BaseAddress, NULL,
XFL_AMD_CMD_UNLOCK_BYPASS_RESET1);
DevDataPtr->WriteFlash(BaseAddress, NULL,
@ -1606,6 +1765,95 @@ static int WriteBuffer16(XFlash * InstancePtr, void *DestPtr,
return (XST_SUCCESS);
}
/*****************************************************************************/
/**
*
* This function is used to program Buffer sized data. It does not erase
* the flash first and will fail if the block(s) are not erased first. The
* device(s) are programmed in parallel.
*
* @param InstancePtr is the instance to work on.
* @param DestPtr is the physical destination address in flash memory
* space.
* @param SrcPtr is the source data.
* @param Bytes is the number of bytes to program.
*
* @return
* - XST_SUCCESS if successful.
* - XFLASH_ERROR if a write error occurred. This error is
* usually device specific.
*
* @note None.
*
******************************************************************************/
int WriteSingleBuffer(XFlash * InstancePtr, void *DestPtr,
void *SrcPtr, u32 Bytes)
{
u16 *SourcePtr = (u16*)SrcPtr;
u32 DestinationPtr = (u32)DestPtr;
u32 BaseAddress;
u32 Index = 0;
int Status = XST_SUCCESS;
XFlashVendorData_Amd *DevDataPtr;
u32 SectorAddress;
u32 WordCount = Bytes/2;
u16 StartRegion;
u16 EndRegion;
u16 StartBlock;
u16 EndBlock;
u32 Dummy;
u32 BlockAddress;
volatile u16 FlashStatus;
XFlashGeometry *GeomPtr;
GeomPtr = &InstancePtr->Geometry;
Status = XFlashGeometry_ToBlock(GeomPtr, (u32)DestPtr/2, &StartRegion,
&StartBlock, &Dummy);
(void) XFlashGeometry_ToAbsolute(GeomPtr, StartRegion, StartBlock, 0,
&BlockAddress);
SectorAddress = BlockAddress *2;
DevDataPtr = GET_PARTDATA(InstancePtr);
BaseAddress = InstancePtr->Geometry.BaseAddress;
DestinationPtr = DestinationPtr/2;
/* Wait until device is ready. */
AmdDevice_is_Ready(InstancePtr);
/* Send Status Register Clear Command. */
DevDataPtr->SendCmd(BaseAddress,XFL_AMD_CMD1_ADDR,
XFL_AMD_CMD_STATUS_REG_CLEAR);
/* Send two Unlock cycles Commands. */
DevDataPtr->SendCmdSeq(BaseAddress,
XFL_AMD_CMD1_ADDR, XFL_AMD_CMD2_ADDR,
XFL_AMD_CMD1_DATA, XFL_AMD_CMD2_DATA);
/* Send Write to Buffer Command. */
DevDataPtr->SendCmd(BaseAddress,(SectorAddress/2),
XFL_AMD_CMD_WRITE_BUFFER);
/* Issue Number of words to Write at sector address. */
DevDataPtr->SendCmd(BaseAddress,(SectorAddress/2),
(WordCount - 1));
Index = 0;
/* Write Data to Buffer. */
while (WordCount != NULL) {
DevDataPtr->WriteFlash(BaseAddress,
(u32)DestinationPtr, SourcePtr[Index]);
DestinationPtr++;
Index++;
WordCount -= 1;
}
/* Send Write buffer program confirm command. */
DevDataPtr->WriteFlash(BaseAddress,(SectorAddress/2),
XFL_AMD_CMD_PROGRAM_BUFFER);
Status = DevDataPtr->PollSR(BaseAddress,(u32)(DestinationPtr * 2));
if (Status != XFLASH_READY) {
(void) XFlashAmd_ResetBank(InstancePtr, (u32)DestPtr,
Bytes);
return Status;
}
return XST_SUCCESS;
}
/*****************************************************************************/
/**
@ -1640,6 +1888,13 @@ static int WriteBuffer32(XFlash * InstancePtr, void *DestPtr,
int Status = XST_SUCCESS;
XFlashVendorData_Amd *DevDataPtr;
/*
* Make sure DestPtr and SrcPtr are aligned to a 16-bit word.
*/
if (((int) SourcePtr & 3) || ((int) DestinationPtr & 3)) {
return (XFLASH_ALIGNMENT_ERROR);
}
DevDataPtr = GET_PARTDATA(InstancePtr);
BaseAddress = InstancePtr->Geometry.BaseAddress;
@ -1851,19 +2106,15 @@ static int PollSR8(u32 BaseAddr, u32 BlockAddr)
******************************************************************************/
static int PollSR16(u32 BaseAddr, u32 BlockAddr)
{
u16 StatusReg1;
u16 StatusReg2;
volatile u16 StatusReg1;
volatile u16 StatusReg2;
while(TRUE) {
/*
* Read DQ5 and DQ6 (into word).
*/
/* Read DQ5 and DQ6 (into word). */
StatusReg1 = READ_FLASH_16(((volatile u16*)BaseAddr) +
BlockAddr);
/*
* Read DQ6 (into another word).
*/
/* Read DQ6 (into another word). */
StatusReg2 = READ_FLASH_16(((volatile u16*)BaseAddr) +
BlockAddr);
@ -1873,23 +2124,17 @@ static int PollSR16(u32 BaseAddr, u32 BlockAddr)
*/
if((StatusReg1 & XFL_AMD_SR_ERASE_COMPL_MASK) ==
(StatusReg2 & XFL_AMD_SR_ERASE_COMPL_MASK)) {
/*
* DQ6 == NO Toggle.
*/
/* DQ6 == NO Toggle. */
return (XFLASH_READY);
}
/*
* If DQ5 is zero then operation is not yet complete.
*/
/* If DQ5 is zero then operation is not yet complete. */
if((StatusReg2 & XFL_AMD_SR_ERASE_ERROR_MASK) !=
XFL_AMD_SR_ERASE_ERROR_MASK) {
continue;
}
/*
* Else (DQ5 == 1), read DQ6 twice.
*/
/* Else (DQ5 == 1), read DQ6 twice. */
StatusReg1 = READ_FLASH_16(((volatile u16*)BaseAddr) +
BlockAddr);
StatusReg2 = READ_FLASH_16(((volatile u16*)BaseAddr) +
@ -1901,9 +2146,7 @@ static int PollSR16(u32 BaseAddr, u32 BlockAddr)
*/
if((StatusReg1 & XFL_AMD_SR_ERASE_COMPL_MASK) ==
(StatusReg2 & XFL_AMD_SR_ERASE_COMPL_MASK)) {
/*
* DQ6 == NO Toggle.
*/
/* DQ6 == NO Toggle. */
return (XFLASH_READY);
}
else {
@ -2082,6 +2325,7 @@ static u16 EnqueueEraseBlocks(XFlash * InstancePtr, u16 *Region,
u32 BlockAddress;
XFlashGeometry *GeomPtr;
XFlashVendorData_Amd *DevDataPtr;
volatile u16 FlashStatus;
/*
* If for some reason the maximum number of blocks to enqueue is
@ -2100,9 +2344,11 @@ static u16 EnqueueEraseBlocks(XFlash * InstancePtr, u16 *Region,
(void) XFlashGeometry_ToAbsolute(GeomPtr, *Region, *Block, 0,
&BlockAddress);
/*
* Write Block Erase command.
*/
/* Send Status register clear command. */
DevDataPtr->SendCmd(GeomPtr->BaseAddress,XFL_AMD_CMD1_ADDR,
XFL_AMD_CMD_STATUS_REG_CLEAR);
/* Write Block Erase command. */
DevDataPtr->SendCmdSeq(GeomPtr->BaseAddress,
XFL_AMD_CMD1_ADDR, XFL_AMD_CMD2_ADDR,
XFL_AMD_CMD1_DATA, XFL_AMD_CMD2_DATA);
@ -2115,20 +2361,10 @@ static u16 EnqueueEraseBlocks(XFlash * InstancePtr, u16 *Region,
DevDataPtr->WriteFlash(GeomPtr->BaseAddress, BlockAddress,
XFL_AMD_CMD_ERASE_BLOCK);
/*
* Wait until Program/Erase Controller starts.
*/
while (((DevDataPtr->GetStatus(GeomPtr->BaseAddress,BlockAddress)) &
(XFL_AMD_SR_ERASE_START_MASK)) == NULL);
/*
* Increment Region/Block.
*/
/* Increment Region/Block. */
XFL_GEOMETRY_INCREMENT(GeomPtr, *Region, *Block);
/*
* Return the number of blocks enqueued.
*/
/* Return the number of blocks enqueued. */
return (1);
}