forked from Imagelibrary/rtems
bsps/shared/xnandpsu: Add opportunistic page cache
Add an opportunistic page cache to the xnandpsu driver since it does not implement partial page reads and common filesystem access patterns perform multiple reads from the same page. This has been seen to provide a 10x speedup to read speeds and a 2x speedup on first initialization when used with JFFS2.
This commit is contained in:
committed by
Joel Sherrill
parent
a7730cf1b1
commit
33379dcfc4
@@ -217,6 +217,12 @@ extern "C" {
|
||||
#define XNANDPSU_NVDDR_CLK_5 ((u16)100U * (u16)1000U * (u16)1000U)
|
||||
|
||||
#define XNANDPSU_MAX_TIMING_MODE 5
|
||||
|
||||
#ifdef __rtems__
|
||||
#define XNANDPSU_PAGE_CACHE_UNAVAILABLE -2
|
||||
#define XNANDPSU_PAGE_CACHE_NONE -1
|
||||
#endif
|
||||
|
||||
/**
|
||||
* The XNandPsu_Config structure contains configuration information for NAND
|
||||
* controller.
|
||||
@@ -390,6 +396,9 @@ typedef struct {
|
||||
XNandPsu_EccCfg EccCfg; /**< ECC configuration */
|
||||
XNandPsu_Geometry Geometry; /**< Flash geometry */
|
||||
XNandPsu_Features Features; /**< ONFI features */
|
||||
#ifdef __rtems__
|
||||
int32_t PartialDataPageIndex; /**< Cached page index */
|
||||
#endif
|
||||
#ifdef __ICCARM__
|
||||
u8 PartialDataBuf[XNANDPSU_MAX_PAGE_SIZE]; /**< Partial read/write buffer */
|
||||
#pragma pack(pop)
|
||||
|
||||
@@ -244,6 +244,11 @@ s32 XNandPsu_CfgInitialize(XNandPsu *InstancePtr, XNandPsu_Config *ConfigPtr,
|
||||
InstancePtr->DmaMode = XNANDPSU_MDMA;
|
||||
InstancePtr->IsReady = XIL_COMPONENT_IS_READY;
|
||||
|
||||
#ifdef __rtems__
|
||||
/* Set page cache to unavailable */
|
||||
InstancePtr->PartialDataPageIndex = XNANDPSU_PAGE_CACHE_UNAVAILABLE;
|
||||
#endif
|
||||
|
||||
/* Initialize the NAND flash targets */
|
||||
Status = XNandPsu_FlashInit(InstancePtr);
|
||||
if (Status != XST_SUCCESS) {
|
||||
@@ -278,6 +283,11 @@ s32 XNandPsu_CfgInitialize(XNandPsu *InstancePtr, XNandPsu_Config *ConfigPtr,
|
||||
#endif
|
||||
goto Out;
|
||||
}
|
||||
|
||||
#ifdef __rtems__
|
||||
/* Set page cache to none */
|
||||
InstancePtr->PartialDataPageIndex = XNANDPSU_PAGE_CACHE_NONE;
|
||||
#endif
|
||||
Out:
|
||||
return Status;
|
||||
}
|
||||
@@ -1454,6 +1464,12 @@ s32 XNandPsu_Write(XNandPsu *InstancePtr, u64 Offset, u64 Length, u8 *SrcBuf)
|
||||
goto Out;
|
||||
}
|
||||
|
||||
#ifdef __rtems__
|
||||
if (InstancePtr->PartialDataPageIndex != XNANDPSU_PAGE_CACHE_UNAVAILABLE) {
|
||||
/* All writes invalidate the page cache */
|
||||
InstancePtr->PartialDataPageIndex = XNANDPSU_PAGE_CACHE_NONE;
|
||||
}
|
||||
#endif
|
||||
while (LengthVar > 0U) {
|
||||
Block = (u32) (OffsetVar/InstancePtr->Geometry.BlockSize);
|
||||
/*
|
||||
@@ -1619,9 +1635,34 @@ s32 XNandPsu_Read(XNandPsu *InstancePtr, u64 Offset, u64 Length, u8 *DestBuf)
|
||||
InstancePtr->Geometry.BytesPerPage :
|
||||
(u32)LengthVar;
|
||||
}
|
||||
#ifdef __rtems__
|
||||
if (Page == InstancePtr->PartialDataPageIndex) {
|
||||
/*
|
||||
* This is a whole page read for the currently cached
|
||||
* page. It will not be taken care of below, so perform
|
||||
* the copy here.
|
||||
*/
|
||||
if (PartialBytes == 0U) {
|
||||
(void)Xil_MemCpy(DestBufPtr,
|
||||
&InstancePtr->PartialDataBuf[0],
|
||||
NumBytes);
|
||||
}
|
||||
} else {
|
||||
#endif
|
||||
/* Read page */
|
||||
Status = XNandPsu_ReadPage(InstancePtr, Target, Page, 0U,
|
||||
BufPtr);
|
||||
#ifdef __rtems__
|
||||
if (PartialBytes > 0U &&
|
||||
InstancePtr->PartialDataPageIndex != XNANDPSU_PAGE_CACHE_UNAVAILABLE) {
|
||||
/*
|
||||
* Partial read into page cache. Update the
|
||||
* cached page index.
|
||||
*/
|
||||
InstancePtr->PartialDataPageIndex = Page;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
if (Status != XST_SUCCESS) {
|
||||
goto Out;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user