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:
Shakti Bhatnagar 2015-01-12 19:01:22 +05:30 committed by Suneel Garapati
parent 3f752a53a6
commit 1c36cca35c
3 changed files with 133 additions and 70 deletions

View file

@ -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;
}
/*****************************************************************************/
/**
*

View file

@ -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
*/

View file

@ -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;