123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197 |
- 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_ */
|