198 lines
7.1 KiB
Diff
198 lines
7.1 KiB
Diff
From 6d274379f584a638c1f2b4b8a19014d4baef1d9f Mon Sep 17 00:00:00 2001
|
|
From: sahil <sahil@arm.com>
|
|
Date: Thu, 11 Aug 2022 11:26:29 +0530
|
|
Subject: [PATCH] Platform/ARM/N1Sdp: manually poll QSPI status bit after
|
|
erase/write
|
|
|
|
This patch adds a function to poll Nor flash memory's status register
|
|
bit (WIP bit) to wait for an erase/write operation to complete.
|
|
The polling timeout is set to 1 second.
|
|
|
|
Upstream-Status: Pending
|
|
Signed-off-by: Xueliang Zhong <xueliang.zhong@arm.com>
|
|
Signed-off-by: sahil <sahil@arm.com>
|
|
Change-Id: Ie678b7586671964ae0f8506a0542d73cbddddfe4
|
|
---
|
|
.../Drivers/CadenceQspiDxe/CadenceQspiDxe.inf | 1 +
|
|
.../Drivers/CadenceQspiDxe/CadenceQspiReg.h | 6 +-
|
|
.../N1Sdp/Drivers/CadenceQspiDxe/NorFlash.c | 80 ++++++++++++++++++-
|
|
.../N1Sdp/Drivers/CadenceQspiDxe/NorFlash.h | 5 ++
|
|
4 files changed, 88 insertions(+), 4 deletions(-)
|
|
|
|
diff --git a/Platform/ARM/N1Sdp/Drivers/CadenceQspiDxe/CadenceQspiDxe.inf b/Platform/ARM/N1Sdp/Drivers/CadenceQspiDxe/CadenceQspiDxe.inf
|
|
index 4f20c3ba..7a39eb2d 100644
|
|
--- a/Platform/ARM/N1Sdp/Drivers/CadenceQspiDxe/CadenceQspiDxe.inf
|
|
+++ b/Platform/ARM/N1Sdp/Drivers/CadenceQspiDxe/CadenceQspiDxe.inf
|
|
@@ -39,6 +39,7 @@
|
|
MemoryAllocationLib
|
|
NorFlashInfoLib
|
|
NorFlashPlatformLib
|
|
+ TimerLib
|
|
UefiBootServicesTableLib
|
|
UefiDriverEntryPoint
|
|
UefiLib
|
|
diff --git a/Platform/ARM/N1Sdp/Drivers/CadenceQspiDxe/CadenceQspiReg.h b/Platform/ARM/N1Sdp/Drivers/CadenceQspiDxe/CadenceQspiReg.h
|
|
index fe3b327c..1971631d 100644
|
|
--- a/Platform/ARM/N1Sdp/Drivers/CadenceQspiDxe/CadenceQspiReg.h
|
|
+++ b/Platform/ARM/N1Sdp/Drivers/CadenceQspiDxe/CadenceQspiReg.h
|
|
@@ -16,13 +16,15 @@
|
|
#define CDNS_QSPI_FLASH_CMD_CTRL_REG_ADDR_BIT_POS 19
|
|
#define CDNS_QSPI_FLASH_CMD_CTRL_REG_ADDR_BYTE_BIT_POS 16
|
|
#define CDNS_QSPI_FLASH_CMD_CTRL_REG_STATUS_BIT 0x02
|
|
-#define CDNS_QSPI_FLASH_CMD_CTRL_REG_ADDR_BYTE_4B 0x03
|
|
-#define CDNS_QSPI_FLASH_CMD_CTRL_REG_ADDR_BYTE_3B 0x02
|
|
#define CDNS_QSPI_FLASH_CMD_CTRL_REG_OPCODE_BIT_POS 24
|
|
#define CDNS_QSPI_FLASH_CMD_CTRL_REG_READ_ENABLE 0x01
|
|
#define CDNS_QSPI_FLASH_CMD_CTRL_REG_READ_BYTE_3B 0x02
|
|
#define CDNS_QSPI_FLASH_CMD_CTRL_REG_READEN_BIT_POS 23
|
|
#define CDNS_QSPI_FLASH_CMD_CTRL_REG_READBYTE_BIT_POS 20
|
|
+#define CDNS_QSPI_FLASH_CMD_CTRL_REG_DUMMY_8C 0x8
|
|
+#define CDNS_QSPI_FLASH_CMD_CTRL_REG_DUMMY_BIT_POS 7
|
|
+#define CDNS_QSPI_FLASH_CMD_CTRL_REG_NUM_DATA_BYTES(x) ((x - 1) << CDNS_QSPI_FLASH_CMD_CTRL_REG_READBYTE_BIT_POS)
|
|
+#define CDNS_QSPI_FLASH_CMD_CTRL_REG_NUM_ADDR_BYTES(x) ((x - 1) << CDNS_QSPI_FLASH_CMD_CTRL_REG_ADDR_BYTE_BIT_POS)
|
|
|
|
#define CDNS_QSPI_FLASH_CMD_READ_DATA_REG_OFFSET 0xA0
|
|
|
|
diff --git a/Platform/ARM/N1Sdp/Drivers/CadenceQspiDxe/NorFlash.c b/Platform/ARM/N1Sdp/Drivers/CadenceQspiDxe/NorFlash.c
|
|
index 188c75e2..6832351a 100644
|
|
--- a/Platform/ARM/N1Sdp/Drivers/CadenceQspiDxe/NorFlash.c
|
|
+++ b/Platform/ARM/N1Sdp/Drivers/CadenceQspiDxe/NorFlash.c
|
|
@@ -10,6 +10,7 @@
|
|
#include <Library/MemoryAllocationLib.h>
|
|
#include <Library/NorFlashInfoLib.h>
|
|
#include <Library/PcdLib.h>
|
|
+#include <Library/TimerLib.h>
|
|
#include <Library/UefiBootServicesTableLib.h>
|
|
#include <Library/UefiLib.h>
|
|
|
|
@@ -184,6 +185,74 @@ FreeInstance:
|
|
return Status;
|
|
}
|
|
|
|
+/**
|
|
+ Converts milliseconds into number of ticks of the performance counter.
|
|
+
|
|
+ @param[in] Milliseconds Milliseconds to convert into ticks.
|
|
+
|
|
+ @retval Milliseconds expressed as number of ticks.
|
|
+
|
|
+**/
|
|
+STATIC
|
|
+UINT64
|
|
+MilliSecondsToTicks (
|
|
+ IN UINTN Milliseconds
|
|
+ )
|
|
+{
|
|
+ CONST UINT64 NanoSecondsPerTick = GetTimeInNanoSecond (1);
|
|
+
|
|
+ return (Milliseconds * 1000000) / NanoSecondsPerTick;
|
|
+}
|
|
+
|
|
+/**
|
|
+ Poll Status register for NOR flash erase/write completion.
|
|
+
|
|
+ @param[in] Instance NOR flash Instance.
|
|
+
|
|
+ @retval EFI_SUCCESS Request is executed successfully.
|
|
+ @retval EFI_TIMEOUT Operation timed out.
|
|
+ @retval EFI_DEVICE_ERROR Controller operartion failed.
|
|
+
|
|
+**/
|
|
+STATIC
|
|
+EFI_STATUS
|
|
+NorFlashPollStatusRegister (
|
|
+ IN NOR_FLASH_INSTANCE *Instance
|
|
+ )
|
|
+{
|
|
+ BOOLEAN SRegDone;
|
|
+ UINT32 val;
|
|
+
|
|
+ val = SPINOR_OP_RDSR << CDNS_QSPI_FLASH_CMD_CTRL_REG_OPCODE_BIT_POS |
|
|
+ CDNS_QSPI_FLASH_CMD_CTRL_REG_READ_ENABLE << CDNS_QSPI_FLASH_CMD_CTRL_REG_READEN_BIT_POS |
|
|
+ CDNS_QSPI_FLASH_CMD_CTRL_REG_NUM_DATA_BYTES(1) |
|
|
+ CDNS_QSPI_FLASH_CMD_CTRL_REG_DUMMY_8C << CDNS_QSPI_FLASH_CMD_CTRL_REG_DUMMY_BIT_POS;
|
|
+
|
|
+ CONST UINT64 TickOut =
|
|
+ GetPerformanceCounter () + MilliSecondsToTicks (SPINOR_SR_WIP_POLL_TIMEOUT_MS);
|
|
+
|
|
+ do {
|
|
+ if (GetPerformanceCounter () > TickOut) {
|
|
+ DEBUG ((
|
|
+ DEBUG_ERROR,
|
|
+ "NorFlashPollStatusRegister: Timeout waiting for erase/write.\n"
|
|
+ ));
|
|
+ return EFI_TIMEOUT;
|
|
+ }
|
|
+
|
|
+ if (EFI_ERROR (CdnsQspiExecuteCommand (Instance, val))) {
|
|
+ return EFI_DEVICE_ERROR;
|
|
+ }
|
|
+
|
|
+ SRegDone =
|
|
+ (MmioRead8 (Instance->HostRegisterBaseAddress + CDNS_QSPI_FLASH_CMD_READ_DATA_REG_OFFSET)
|
|
+ & SPINOR_SR_WIP) == 0;
|
|
+
|
|
+ } while (!SRegDone);
|
|
+
|
|
+ return EFI_SUCCESS;
|
|
+}
|
|
+
|
|
/**
|
|
Check whether NOR flash opertions are Locked.
|
|
|
|
@@ -305,12 +374,16 @@ NorFlashEraseSingleBlock (
|
|
|
|
DevConfigVal = SPINOR_OP_BE_4K << CDNS_QSPI_FLASH_CMD_CTRL_REG_OPCODE_BIT_POS |
|
|
CDNS_QSPI_FLASH_CMD_CTRL_REG_ADDR_ENABLE << CDNS_QSPI_FLASH_CMD_CTRL_REG_ADDR_BIT_POS |
|
|
- CDNS_QSPI_FLASH_CMD_CTRL_REG_ADDR_BYTE_3B << CDNS_QSPI_FLASH_CMD_CTRL_REG_ADDR_BYTE_BIT_POS;
|
|
+ CDNS_QSPI_FLASH_CMD_CTRL_REG_NUM_ADDR_BYTES(3);
|
|
|
|
if (EFI_ERROR (CdnsQspiExecuteCommand (Instance, DevConfigVal))) {
|
|
return EFI_DEVICE_ERROR;
|
|
}
|
|
|
|
+ if (EFI_ERROR (NorFlashPollStatusRegister (Instance))) {
|
|
+ return EFI_DEVICE_ERROR;
|
|
+ }
|
|
+
|
|
return EFI_SUCCESS;
|
|
}
|
|
|
|
@@ -383,6 +456,9 @@ NorFlashWriteSingleWord (
|
|
return EFI_DEVICE_ERROR;
|
|
}
|
|
MmioWrite32 (WordAddress, WriteData);
|
|
+ if (EFI_ERROR (NorFlashPollStatusRegister (Instance))) {
|
|
+ return EFI_DEVICE_ERROR;
|
|
+ }
|
|
return EFI_SUCCESS;
|
|
}
|
|
|
|
@@ -907,7 +983,7 @@ NorFlashReadID (
|
|
|
|
val = SPINOR_OP_RDID << CDNS_QSPI_FLASH_CMD_CTRL_REG_OPCODE_BIT_POS |
|
|
CDNS_QSPI_FLASH_CMD_CTRL_REG_READ_ENABLE << CDNS_QSPI_FLASH_CMD_CTRL_REG_READEN_BIT_POS |
|
|
- CDNS_QSPI_FLASH_CMD_CTRL_REG_ADDR_BYTE_3B << CDNS_QSPI_FLASH_CMD_CTRL_REG_READBYTE_BIT_POS;
|
|
+ CDNS_QSPI_FLASH_CMD_CTRL_REG_NUM_DATA_BYTES(3);
|
|
|
|
if (EFI_ERROR (CdnsQspiExecuteCommand (Instance, val))) {
|
|
return EFI_DEVICE_ERROR;
|
|
diff --git a/Platform/ARM/N1Sdp/Drivers/CadenceQspiDxe/NorFlash.h b/Platform/ARM/N1Sdp/Drivers/CadenceQspiDxe/NorFlash.h
|
|
index e720937e..eb0afc60 100644
|
|
--- a/Platform/ARM/N1Sdp/Drivers/CadenceQspiDxe/NorFlash.h
|
|
+++ b/Platform/ARM/N1Sdp/Drivers/CadenceQspiDxe/NorFlash.h
|
|
@@ -477,8 +477,13 @@ NorFlashReadID (
|
|
OUT UINT8 JedecId[3]
|
|
);
|
|
|
|
+#define SPINOR_SR_WIP BIT0 // Write in progress
|
|
+
|
|
#define SPINOR_OP_WREN 0x06 // Write enable
|
|
#define SPINOR_OP_BE_4K 0x20 // Erase 4KiB block
|
|
#define SPINOR_OP_RDID 0x9f // Read JEDEC ID
|
|
+#define SPINOR_OP_RDSR 0x05 // Read status register
|
|
+
|
|
+#define SPINOR_SR_WIP_POLL_TIMEOUT_MS 1000u // Status Register read timeout
|
|
|
|
#endif /* NOR_FLASH_DXE_H_ */
|