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:
Kinsey Moore
2024-03-01 15:39:27 -06:00
committed by Joel Sherrill
parent a7730cf1b1
commit 33379dcfc4
2 changed files with 50 additions and 0 deletions

View File

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

View File

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