nandps8_v2_0: Provided option to store bbt signature in no oob area at run time.
Provided option to store bbt signature in no obb area at run time by calling XNandPs8_DisableBbtOobMode API. Signed-off-by: Shakti Bhatnagar <shaktib@xilinx.com>
This commit is contained in:
parent
3f752a53a6
commit
1c36cca35c
3 changed files with 133 additions and 70 deletions
|
@ -827,6 +827,54 @@ void XNandPs8_DisableEccMode(XNandPs8 *InstancePtr)
|
|||
InstancePtr->EccMode = NONE;
|
||||
}
|
||||
|
||||
/*****************************************************************************/
|
||||
/**
|
||||
*
|
||||
* This function enables storing bbt version in oob area.
|
||||
*
|
||||
* @param InstancePtr is a pointer to the XNandPs8 instance.
|
||||
*
|
||||
* @return
|
||||
* None
|
||||
*
|
||||
* @note None
|
||||
*
|
||||
******************************************************************************/
|
||||
void XNandPs8_EnableBbtOobMode(XNandPs8 *InstancePtr)
|
||||
{
|
||||
/*
|
||||
* Assert the input arguments.
|
||||
*/
|
||||
Xil_AssertVoid(InstancePtr != NULL);
|
||||
Xil_AssertVoid(InstancePtr->IsReady == XIL_COMPONENT_IS_READY);
|
||||
InstancePtr->BbtDesc.Option = XNANDPS8_BBT_OOB;
|
||||
InstancePtr->BbtMirrorDesc.Option = XNANDPS8_BBT_OOB;
|
||||
}
|
||||
|
||||
/*****************************************************************************/
|
||||
/**
|
||||
*
|
||||
* This function enables storing bbt version in no oob area i.e. page memory.
|
||||
*
|
||||
* @param InstancePtr is a pointer to the XNandPs8 instance.
|
||||
*
|
||||
* @return
|
||||
* None
|
||||
*
|
||||
* @note None
|
||||
*
|
||||
******************************************************************************/
|
||||
void XNandPs8_DisableBbtOobMode(XNandPs8 *InstancePtr)
|
||||
{
|
||||
/*
|
||||
* Assert the input arguments.
|
||||
*/
|
||||
Xil_AssertVoid(InstancePtr != NULL);
|
||||
Xil_AssertVoid(InstancePtr->IsReady == XIL_COMPONENT_IS_READY);
|
||||
InstancePtr->BbtDesc.Option = XNANDPS8_BBT_NO_OOB;
|
||||
InstancePtr->BbtMirrorDesc.Option = XNANDPS8_BBT_NO_OOB;
|
||||
}
|
||||
|
||||
/*****************************************************************************/
|
||||
/**
|
||||
*
|
||||
|
|
|
@ -202,7 +202,6 @@ extern "C" {
|
|||
#define NVDDR_CLK_3 ((u16)66U * (u16)1000U * (u16)1000U)
|
||||
#define NVDDR_CLK_4 ((u16)83U * (u16)1000U * (u16)1000U)
|
||||
#define NVDDR_CLK_5 ((u16)100U * (u16)1000U * (u16)1000U)
|
||||
//#define XNANDPS8_BBT_NO_OOB
|
||||
|
||||
/**
|
||||
* The XNandPs8_Config structure contains configuration information for NAND
|
||||
|
@ -274,6 +273,14 @@ typedef struct {
|
|||
u32 FeatureVal;
|
||||
} XNandPs8_TimingModeDesc;
|
||||
|
||||
/**
|
||||
* The XNandPs8_BbtOption enum contains the BBT storage option.
|
||||
*/
|
||||
typedef enum {
|
||||
XNANDPS8_BBT_OOB = 0, /**< OOB area */
|
||||
XNANDPS8_BBT_NO_OOB, /**< No OOB i.e page area */
|
||||
} XNandPs8_BbtOption;
|
||||
|
||||
/**
|
||||
* Bad block table descriptor
|
||||
*/
|
||||
|
@ -288,6 +295,7 @@ typedef struct {
|
|||
u8 Version[XNANDPS8_MAX_TARGETS];
|
||||
/**< BBT version */
|
||||
u32 Valid; /**< BBT descriptor is valid or not */
|
||||
XNandPs8_BbtOption Option; /**< BBT Oob option enabled/disabled */
|
||||
} XNandPs8_BbtDesc;
|
||||
|
||||
/**
|
||||
|
@ -558,6 +566,9 @@ void XNandPs8_DisableEccMode(XNandPs8 *InstancePtr);
|
|||
void XNandPs8_Prepare_Cmd(XNandPs8 *InstancePtr, u8 Cmd1, u8 Cmd2, u8 EccState,
|
||||
u8 DmaMode, u8 AddrCycles);
|
||||
|
||||
void XNandPs8_EnableBbtOobMode(XNandPs8 *InstancePtr);
|
||||
|
||||
void XNandPs8_DisableBbtOobMode(XNandPs8 *InstancePtr);
|
||||
/*
|
||||
* XNandPs8_LookupConfig in xnandps8_sinit.c
|
||||
*/
|
||||
|
|
|
@ -122,6 +122,7 @@ void XNandPs8_InitBbtDesc(XNandPs8 *InstancePtr)
|
|||
InstancePtr->BbtDesc.Version[Index] = 0U;
|
||||
}
|
||||
InstancePtr->BbtDesc.Valid = 0U;
|
||||
InstancePtr->BbtDesc.Option = XNANDPS8_BBT_OOB;
|
||||
|
||||
/*
|
||||
* Initialize mirror Bad Block Table(BBT)
|
||||
|
@ -148,6 +149,7 @@ void XNandPs8_InitBbtDesc(XNandPs8 *InstancePtr)
|
|||
InstancePtr->BbtMirrorDesc.Version[Index] = 0U;
|
||||
}
|
||||
InstancePtr->BbtMirrorDesc.Valid = 0U;
|
||||
InstancePtr->BbtMirrorDesc.Option = XNANDPS8_BBT_OOB;
|
||||
|
||||
/*
|
||||
* Initialize Bad block search pattern structure
|
||||
|
@ -458,10 +460,10 @@ static s32 XNandPs8_ReadBbt(XNandPs8 *InstancePtr, u32 Target)
|
|||
goto Out;
|
||||
}
|
||||
|
||||
#ifdef XNANDPS8_BBT_NO_OOB
|
||||
BufPtr = BufPtr + Desc->VerOffset +
|
||||
XNANDPS8_BBT_VERSION_LENGTH;
|
||||
#endif
|
||||
if (Desc->Option == XNANDPS8_BBT_NO_OOB){
|
||||
BufPtr = BufPtr + Desc->VerOffset +
|
||||
XNANDPS8_BBT_VERSION_LENGTH;
|
||||
}
|
||||
/*
|
||||
* Convert flash BBT to memory based BBT
|
||||
*/
|
||||
|
@ -485,10 +487,10 @@ static s32 XNandPs8_ReadBbt(XNandPs8 *InstancePtr, u32 Target)
|
|||
if (Status != XST_SUCCESS) {
|
||||
goto Out;
|
||||
}
|
||||
#ifdef XNANDPS8_BBT_NO_OOB
|
||||
BufPtr = BufPtr + Desc->VerOffset +
|
||||
XNANDPS8_BBT_VERSION_LENGTH;
|
||||
#endif
|
||||
if(Desc->Option == XNANDPS8_BBT_NO_OOB){
|
||||
BufPtr = BufPtr + Desc->VerOffset +
|
||||
XNANDPS8_BBT_VERSION_LENGTH;
|
||||
}
|
||||
/*
|
||||
* Convert flash BBT to memory based BBT
|
||||
*/
|
||||
|
@ -512,10 +514,11 @@ static s32 XNandPs8_ReadBbt(XNandPs8 *InstancePtr, u32 Target)
|
|||
if (Status != XST_SUCCESS) {
|
||||
goto Out;
|
||||
}
|
||||
#ifdef XNANDPS8_BBT_NO_OOB
|
||||
BufPtr = BufPtr + Desc->VerOffset +
|
||||
XNANDPS8_BBT_VERSION_LENGTH;
|
||||
#endif
|
||||
|
||||
if(Desc->Option == XNANDPS8_BBT_NO_OOB){
|
||||
BufPtr = BufPtr + Desc->VerOffset +
|
||||
XNANDPS8_BBT_VERSION_LENGTH;
|
||||
}
|
||||
|
||||
/*
|
||||
* Convert flash BBT to memory based BBT
|
||||
|
@ -532,10 +535,10 @@ static s32 XNandPs8_ReadBbt(XNandPs8 *InstancePtr, u32 Target)
|
|||
if (Status != XST_SUCCESS) {
|
||||
goto Out;
|
||||
}
|
||||
#ifdef XNANDPS8_BBT_NO_OOB
|
||||
if(Desc->Option == XNANDPS8_BBT_NO_OOB){
|
||||
BufPtr = BufPtr + Desc->VerOffset +
|
||||
XNANDPS8_BBT_VERSION_LENGTH;
|
||||
#endif
|
||||
}
|
||||
/*
|
||||
* Convert flash BBT to memory based BBT
|
||||
*/
|
||||
|
@ -560,10 +563,10 @@ static s32 XNandPs8_ReadBbt(XNandPs8 *InstancePtr, u32 Target)
|
|||
if (Status != XST_SUCCESS) {
|
||||
goto Out;
|
||||
}
|
||||
#ifdef XNANDPS8_BBT_NO_OOB
|
||||
if(Desc->Option == XNANDPS8_BBT_NO_OOB){
|
||||
BufPtr = BufPtr + Desc->VerOffset +
|
||||
XNANDPS8_BBT_VERSION_LENGTH;
|
||||
#endif
|
||||
}
|
||||
|
||||
/*
|
||||
* Convert flash BBT to memory based BBT
|
||||
|
@ -627,13 +630,13 @@ static s32 XNandPs8_SearchBbt(XNandPs8 *InstancePtr, XNandPs8_BbtDesc *Desc,
|
|||
PageOff = (StartBlock - Block) *
|
||||
InstancePtr->Geometry.PagesPerBlock;
|
||||
|
||||
#ifdef XNANDPS8_BBT_NO_OOB
|
||||
BlockOff = (u64)PageOff * (u64)InstancePtr->Geometry.BytesPerPage;
|
||||
Status = XNandPs8_Read(InstancePtr, BlockOff,
|
||||
Desc->SigLength + Desc->SigOffset , &Buf[0]);
|
||||
#else
|
||||
Status = XNandPs8_ReadSpareBytes(InstancePtr, PageOff, &Buf[0]);
|
||||
#endif
|
||||
if(Desc->Option == XNANDPS8_BBT_NO_OOB){
|
||||
BlockOff = (u64)PageOff * (u64)InstancePtr->Geometry.BytesPerPage;
|
||||
Status = XNandPs8_Read(InstancePtr, BlockOff,
|
||||
Desc->SigLength + Desc->SigOffset , &Buf[0]);
|
||||
}else{
|
||||
Status = XNandPs8_ReadSpareBytes(InstancePtr, PageOff, &Buf[0]);
|
||||
}
|
||||
if (Status != XST_SUCCESS) {
|
||||
continue;
|
||||
}
|
||||
|
@ -751,9 +754,9 @@ static s32 XNandPs8_WriteBbt(XNandPs8 *InstancePtr, XNandPs8_BbtDesc *Desc,
|
|||
*/
|
||||
memset(Buf, 0xff, BufLen);
|
||||
|
||||
#ifdef XNANDPS8_BBT_NO_OOB
|
||||
BufPtr = BufPtr + Desc->VerOffset + XNANDPS8_BBT_VERSION_LENGTH;
|
||||
#endif
|
||||
if(Desc->Option == XNANDPS8_BBT_NO_OOB){
|
||||
BufPtr = BufPtr + Desc->VerOffset + XNANDPS8_BBT_VERSION_LENGTH;
|
||||
}
|
||||
/*
|
||||
* Loop through the number of blocks
|
||||
*/
|
||||
|
@ -779,52 +782,53 @@ static s32 XNandPs8_WriteBbt(XNandPs8 *InstancePtr, XNandPs8_BbtDesc *Desc,
|
|||
goto Out;
|
||||
}
|
||||
|
||||
#ifdef XNANDPS8_BBT_NO_OOB
|
||||
/*
|
||||
* Copy the signature and version to the Buffer
|
||||
*/
|
||||
memcpy(Buf + Desc->SigOffset, &Desc->Signature[0],
|
||||
if(Desc->Option == XNANDPS8_BBT_NO_OOB){
|
||||
/*
|
||||
* Copy the signature and version to the Buffer
|
||||
*/
|
||||
memcpy(Buf + Desc->SigOffset, &Desc->Signature[0],
|
||||
Desc->SigLength);
|
||||
memcpy(Buf + Desc->VerOffset, &Desc->Version[Target], 1U);
|
||||
/*
|
||||
* Write the Buffer to page offset
|
||||
*/
|
||||
Offset = (u64)Desc->PageOffset[Target] *
|
||||
(u64)InstancePtr->Geometry.BytesPerPage;
|
||||
Status = XNandPs8_Write(InstancePtr, Offset, BufLen, &Buf[0]);
|
||||
if (Status != XST_SUCCESS) {
|
||||
goto Out;
|
||||
}
|
||||
#else
|
||||
/*
|
||||
* Write the BBT to page offset
|
||||
*/
|
||||
Offset = (u64)Desc->PageOffset[Target] *
|
||||
(u64)InstancePtr->Geometry.BytesPerPage;
|
||||
Status = XNandPs8_Write(InstancePtr, Offset, BbtLen, &Buf[0]);
|
||||
if (Status != XST_SUCCESS) {
|
||||
goto Out;
|
||||
}
|
||||
/*
|
||||
* Write the signature and version in the spare data area
|
||||
*/
|
||||
memset(SpareBuf, 0xff, InstancePtr->Geometry.SpareBytesPerPage);
|
||||
Status = XNandPs8_ReadSpareBytes(InstancePtr, Desc->PageOffset[Target],
|
||||
&SpareBuf[0]);
|
||||
if (Status != XST_SUCCESS) {
|
||||
goto Out;
|
||||
memcpy(Buf + Desc->VerOffset, &Desc->Version[Target], 1U);
|
||||
/*
|
||||
* Write the Buffer to page offset
|
||||
*/
|
||||
Offset = (u64)Desc->PageOffset[Target] *
|
||||
(u64)InstancePtr->Geometry.BytesPerPage;
|
||||
Status = XNandPs8_Write(InstancePtr, Offset, BufLen, &Buf[0]);
|
||||
if (Status != XST_SUCCESS) {
|
||||
goto Out;
|
||||
}
|
||||
}else{
|
||||
/*
|
||||
* Write the BBT to page offset
|
||||
*/
|
||||
Offset = (u64)Desc->PageOffset[Target] *
|
||||
(u64)InstancePtr->Geometry.BytesPerPage;
|
||||
Status = XNandPs8_Write(InstancePtr, Offset, BbtLen, &Buf[0]);
|
||||
if (Status != XST_SUCCESS) {
|
||||
goto Out;
|
||||
}
|
||||
/*
|
||||
* Write the signature and version in the spare data area
|
||||
*/
|
||||
memset(SpareBuf, 0xff, InstancePtr->Geometry.SpareBytesPerPage);
|
||||
Status = XNandPs8_ReadSpareBytes(InstancePtr, Desc->PageOffset[Target],
|
||||
&SpareBuf[0]);
|
||||
if (Status != XST_SUCCESS) {
|
||||
goto Out;
|
||||
}
|
||||
|
||||
memcpy(SpareBuf + Desc->SigOffset, &Desc->Signature[0],
|
||||
Desc->SigLength);
|
||||
memcpy(SpareBuf + Desc->VerOffset, &Desc->Version[Target], 1U);
|
||||
|
||||
Status = XNandPs8_WriteSpareBytes(InstancePtr,
|
||||
Desc->PageOffset[Target], &SpareBuf[0]);
|
||||
if (Status != XST_SUCCESS) {
|
||||
goto Out;
|
||||
}
|
||||
}
|
||||
|
||||
memcpy(SpareBuf + Desc->SigOffset, &Desc->Signature[0],
|
||||
Desc->SigLength);
|
||||
memcpy(SpareBuf + Desc->VerOffset, &Desc->Version[Target], 1U);
|
||||
|
||||
Status = XNandPs8_WriteSpareBytes(InstancePtr,
|
||||
Desc->PageOffset[Target], &SpareBuf[0]);
|
||||
if (Status != XST_SUCCESS) {
|
||||
goto Out;
|
||||
}
|
||||
#endif
|
||||
Status = XST_SUCCESS;
|
||||
Out:
|
||||
return Status;
|
||||
|
|
Loading…
Add table
Reference in a new issue