0008-Platform-ARM-N1Sdp-manually-poll-QSPI-status-bit-aft.patch 7.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197
  1. From 6d274379f584a638c1f2b4b8a19014d4baef1d9f Mon Sep 17 00:00:00 2001
  2. From: sahil <sahil@arm.com>
  3. Date: Thu, 11 Aug 2022 11:26:29 +0530
  4. Subject: [PATCH] Platform/ARM/N1Sdp: manually poll QSPI status bit after
  5. erase/write
  6. This patch adds a function to poll Nor flash memory's status register
  7. bit (WIP bit) to wait for an erase/write operation to complete.
  8. The polling timeout is set to 1 second.
  9. Upstream-Status: Pending
  10. Signed-off-by: Xueliang Zhong <xueliang.zhong@arm.com>
  11. Signed-off-by: sahil <sahil@arm.com>
  12. Change-Id: Ie678b7586671964ae0f8506a0542d73cbddddfe4
  13. ---
  14. .../Drivers/CadenceQspiDxe/CadenceQspiDxe.inf | 1 +
  15. .../Drivers/CadenceQspiDxe/CadenceQspiReg.h | 6 +-
  16. .../N1Sdp/Drivers/CadenceQspiDxe/NorFlash.c | 80 ++++++++++++++++++-
  17. .../N1Sdp/Drivers/CadenceQspiDxe/NorFlash.h | 5 ++
  18. 4 files changed, 88 insertions(+), 4 deletions(-)
  19. diff --git a/Platform/ARM/N1Sdp/Drivers/CadenceQspiDxe/CadenceQspiDxe.inf b/Platform/ARM/N1Sdp/Drivers/CadenceQspiDxe/CadenceQspiDxe.inf
  20. index 4f20c3ba..7a39eb2d 100644
  21. --- a/Platform/ARM/N1Sdp/Drivers/CadenceQspiDxe/CadenceQspiDxe.inf
  22. +++ b/Platform/ARM/N1Sdp/Drivers/CadenceQspiDxe/CadenceQspiDxe.inf
  23. @@ -39,6 +39,7 @@
  24. MemoryAllocationLib
  25. NorFlashInfoLib
  26. NorFlashPlatformLib
  27. + TimerLib
  28. UefiBootServicesTableLib
  29. UefiDriverEntryPoint
  30. UefiLib
  31. diff --git a/Platform/ARM/N1Sdp/Drivers/CadenceQspiDxe/CadenceQspiReg.h b/Platform/ARM/N1Sdp/Drivers/CadenceQspiDxe/CadenceQspiReg.h
  32. index fe3b327c..1971631d 100644
  33. --- a/Platform/ARM/N1Sdp/Drivers/CadenceQspiDxe/CadenceQspiReg.h
  34. +++ b/Platform/ARM/N1Sdp/Drivers/CadenceQspiDxe/CadenceQspiReg.h
  35. @@ -16,13 +16,15 @@
  36. #define CDNS_QSPI_FLASH_CMD_CTRL_REG_ADDR_BIT_POS 19
  37. #define CDNS_QSPI_FLASH_CMD_CTRL_REG_ADDR_BYTE_BIT_POS 16
  38. #define CDNS_QSPI_FLASH_CMD_CTRL_REG_STATUS_BIT 0x02
  39. -#define CDNS_QSPI_FLASH_CMD_CTRL_REG_ADDR_BYTE_4B 0x03
  40. -#define CDNS_QSPI_FLASH_CMD_CTRL_REG_ADDR_BYTE_3B 0x02
  41. #define CDNS_QSPI_FLASH_CMD_CTRL_REG_OPCODE_BIT_POS 24
  42. #define CDNS_QSPI_FLASH_CMD_CTRL_REG_READ_ENABLE 0x01
  43. #define CDNS_QSPI_FLASH_CMD_CTRL_REG_READ_BYTE_3B 0x02
  44. #define CDNS_QSPI_FLASH_CMD_CTRL_REG_READEN_BIT_POS 23
  45. #define CDNS_QSPI_FLASH_CMD_CTRL_REG_READBYTE_BIT_POS 20
  46. +#define CDNS_QSPI_FLASH_CMD_CTRL_REG_DUMMY_8C 0x8
  47. +#define CDNS_QSPI_FLASH_CMD_CTRL_REG_DUMMY_BIT_POS 7
  48. +#define CDNS_QSPI_FLASH_CMD_CTRL_REG_NUM_DATA_BYTES(x) ((x - 1) << CDNS_QSPI_FLASH_CMD_CTRL_REG_READBYTE_BIT_POS)
  49. +#define CDNS_QSPI_FLASH_CMD_CTRL_REG_NUM_ADDR_BYTES(x) ((x - 1) << CDNS_QSPI_FLASH_CMD_CTRL_REG_ADDR_BYTE_BIT_POS)
  50. #define CDNS_QSPI_FLASH_CMD_READ_DATA_REG_OFFSET 0xA0
  51. diff --git a/Platform/ARM/N1Sdp/Drivers/CadenceQspiDxe/NorFlash.c b/Platform/ARM/N1Sdp/Drivers/CadenceQspiDxe/NorFlash.c
  52. index 188c75e2..6832351a 100644
  53. --- a/Platform/ARM/N1Sdp/Drivers/CadenceQspiDxe/NorFlash.c
  54. +++ b/Platform/ARM/N1Sdp/Drivers/CadenceQspiDxe/NorFlash.c
  55. @@ -10,6 +10,7 @@
  56. #include <Library/MemoryAllocationLib.h>
  57. #include <Library/NorFlashInfoLib.h>
  58. #include <Library/PcdLib.h>
  59. +#include <Library/TimerLib.h>
  60. #include <Library/UefiBootServicesTableLib.h>
  61. #include <Library/UefiLib.h>
  62. @@ -184,6 +185,74 @@ FreeInstance:
  63. return Status;
  64. }
  65. +/**
  66. + Converts milliseconds into number of ticks of the performance counter.
  67. +
  68. + @param[in] Milliseconds Milliseconds to convert into ticks.
  69. +
  70. + @retval Milliseconds expressed as number of ticks.
  71. +
  72. +**/
  73. +STATIC
  74. +UINT64
  75. +MilliSecondsToTicks (
  76. + IN UINTN Milliseconds
  77. + )
  78. +{
  79. + CONST UINT64 NanoSecondsPerTick = GetTimeInNanoSecond (1);
  80. +
  81. + return (Milliseconds * 1000000) / NanoSecondsPerTick;
  82. +}
  83. +
  84. +/**
  85. + Poll Status register for NOR flash erase/write completion.
  86. +
  87. + @param[in] Instance NOR flash Instance.
  88. +
  89. + @retval EFI_SUCCESS Request is executed successfully.
  90. + @retval EFI_TIMEOUT Operation timed out.
  91. + @retval EFI_DEVICE_ERROR Controller operartion failed.
  92. +
  93. +**/
  94. +STATIC
  95. +EFI_STATUS
  96. +NorFlashPollStatusRegister (
  97. + IN NOR_FLASH_INSTANCE *Instance
  98. + )
  99. +{
  100. + BOOLEAN SRegDone;
  101. + UINT32 val;
  102. +
  103. + val = SPINOR_OP_RDSR << CDNS_QSPI_FLASH_CMD_CTRL_REG_OPCODE_BIT_POS |
  104. + CDNS_QSPI_FLASH_CMD_CTRL_REG_READ_ENABLE << CDNS_QSPI_FLASH_CMD_CTRL_REG_READEN_BIT_POS |
  105. + CDNS_QSPI_FLASH_CMD_CTRL_REG_NUM_DATA_BYTES(1) |
  106. + CDNS_QSPI_FLASH_CMD_CTRL_REG_DUMMY_8C << CDNS_QSPI_FLASH_CMD_CTRL_REG_DUMMY_BIT_POS;
  107. +
  108. + CONST UINT64 TickOut =
  109. + GetPerformanceCounter () + MilliSecondsToTicks (SPINOR_SR_WIP_POLL_TIMEOUT_MS);
  110. +
  111. + do {
  112. + if (GetPerformanceCounter () > TickOut) {
  113. + DEBUG ((
  114. + DEBUG_ERROR,
  115. + "NorFlashPollStatusRegister: Timeout waiting for erase/write.\n"
  116. + ));
  117. + return EFI_TIMEOUT;
  118. + }
  119. +
  120. + if (EFI_ERROR (CdnsQspiExecuteCommand (Instance, val))) {
  121. + return EFI_DEVICE_ERROR;
  122. + }
  123. +
  124. + SRegDone =
  125. + (MmioRead8 (Instance->HostRegisterBaseAddress + CDNS_QSPI_FLASH_CMD_READ_DATA_REG_OFFSET)
  126. + & SPINOR_SR_WIP) == 0;
  127. +
  128. + } while (!SRegDone);
  129. +
  130. + return EFI_SUCCESS;
  131. +}
  132. +
  133. /**
  134. Check whether NOR flash opertions are Locked.
  135. @@ -305,12 +374,16 @@ NorFlashEraseSingleBlock (
  136. DevConfigVal = SPINOR_OP_BE_4K << CDNS_QSPI_FLASH_CMD_CTRL_REG_OPCODE_BIT_POS |
  137. CDNS_QSPI_FLASH_CMD_CTRL_REG_ADDR_ENABLE << CDNS_QSPI_FLASH_CMD_CTRL_REG_ADDR_BIT_POS |
  138. - CDNS_QSPI_FLASH_CMD_CTRL_REG_ADDR_BYTE_3B << CDNS_QSPI_FLASH_CMD_CTRL_REG_ADDR_BYTE_BIT_POS;
  139. + CDNS_QSPI_FLASH_CMD_CTRL_REG_NUM_ADDR_BYTES(3);
  140. if (EFI_ERROR (CdnsQspiExecuteCommand (Instance, DevConfigVal))) {
  141. return EFI_DEVICE_ERROR;
  142. }
  143. + if (EFI_ERROR (NorFlashPollStatusRegister (Instance))) {
  144. + return EFI_DEVICE_ERROR;
  145. + }
  146. +
  147. return EFI_SUCCESS;
  148. }
  149. @@ -383,6 +456,9 @@ NorFlashWriteSingleWord (
  150. return EFI_DEVICE_ERROR;
  151. }
  152. MmioWrite32 (WordAddress, WriteData);
  153. + if (EFI_ERROR (NorFlashPollStatusRegister (Instance))) {
  154. + return EFI_DEVICE_ERROR;
  155. + }
  156. return EFI_SUCCESS;
  157. }
  158. @@ -907,7 +983,7 @@ NorFlashReadID (
  159. val = SPINOR_OP_RDID << CDNS_QSPI_FLASH_CMD_CTRL_REG_OPCODE_BIT_POS |
  160. CDNS_QSPI_FLASH_CMD_CTRL_REG_READ_ENABLE << CDNS_QSPI_FLASH_CMD_CTRL_REG_READEN_BIT_POS |
  161. - CDNS_QSPI_FLASH_CMD_CTRL_REG_ADDR_BYTE_3B << CDNS_QSPI_FLASH_CMD_CTRL_REG_READBYTE_BIT_POS;
  162. + CDNS_QSPI_FLASH_CMD_CTRL_REG_NUM_DATA_BYTES(3);
  163. if (EFI_ERROR (CdnsQspiExecuteCommand (Instance, val))) {
  164. return EFI_DEVICE_ERROR;
  165. diff --git a/Platform/ARM/N1Sdp/Drivers/CadenceQspiDxe/NorFlash.h b/Platform/ARM/N1Sdp/Drivers/CadenceQspiDxe/NorFlash.h
  166. index e720937e..eb0afc60 100644
  167. --- a/Platform/ARM/N1Sdp/Drivers/CadenceQspiDxe/NorFlash.h
  168. +++ b/Platform/ARM/N1Sdp/Drivers/CadenceQspiDxe/NorFlash.h
  169. @@ -477,8 +477,13 @@ NorFlashReadID (
  170. OUT UINT8 JedecId[3]
  171. );
  172. +#define SPINOR_SR_WIP BIT0 // Write in progress
  173. +
  174. #define SPINOR_OP_WREN 0x06 // Write enable
  175. #define SPINOR_OP_BE_4K 0x20 // Erase 4KiB block
  176. #define SPINOR_OP_RDID 0x9f // Read JEDEC ID
  177. +#define SPINOR_OP_RDSR 0x05 // Read status register
  178. +
  179. +#define SPINOR_SR_WIP_POLL_TIMEOUT_MS 1000u // Status Register read timeout
  180. #endif /* NOR_FLASH_DXE_H_ */