Spi.h 7.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304
  1. /** @file
  2. *
  3. * Copyright (c) 2023, Yuin Yee, Chew (John) <yuinyee.chew@starfivetech.com>.
  4. *
  5. * SPDX-License-Identifier: BSD-2-Clause-Patent
  6. *
  7. **/
  8. #ifndef __SPI_MASTER_PROTOCOL_H__
  9. #define __SPI_MASTER_PROTOCOL_H__
  10. #include <Library/NorFlashInfoLib.h>
  11. #ifndef BIT
  12. #define BIT(nr) (1 << (nr))
  13. #endif
  14. #define SPI_CPHA BIT(0) // CLock Phase
  15. #define SPI_CPOL BIT(1) // Clock Polarity
  16. #define SPI_MODE_0 (0|0)
  17. #define SPI_MODE_1 (0|SPI_CPHA)
  18. #define SPI_MODE_2 (SPI_CPOL|0)
  19. #define SPI_MODE_3 (SPI_CPOL|SPI_CPHA)
  20. extern EFI_GUID gMarvellSpiMasterProtocolGuid;
  21. typedef struct _SPI_MASTER_PROTOCOL SPI_MASTER_PROTOCOL;
  22. #define SPI_MEM_OP_CMD(__OpCode, __BusWidth) \
  23. { \
  24. .BusWidth = __BusWidth, \
  25. .OpCode = __OpCode, \
  26. .NBytes = 1, \
  27. }
  28. #define SPI_MEM_OP_ADDR(__NBytes, __Val, __BusWidth) \
  29. { \
  30. .NBytes = __NBytes, \
  31. .Val = __Val, \
  32. .BusWidth = __BusWidth, \
  33. }
  34. #define SPI_MEM_OP_NO_ADDR { }
  35. #define SPI_MEM_OP_DUMMY(__NBytes, __BusWidth) \
  36. { \
  37. .NBytes = __NBytes, \
  38. .BusWidth = __BusWidth, \
  39. }
  40. #define SPI_MEM_OP_NO_DUMMY { }
  41. #define SPI_MEM_OP_DATA_IN(__NBytes, __Buf, __BusWidth) \
  42. { \
  43. .Dir = SPI_MEM_DATA_IN, \
  44. .NBytes = __NBytes, \
  45. .Buf.In = __Buf, \
  46. .BusWidth = __BusWidth, \
  47. }
  48. #define SPI_MEM_OP_DATA_OUT(__NBytes, __Buf, __BusWidth) \
  49. { \
  50. .Dir = SPI_MEM_DATA_OUT, \
  51. .NBytes = __NBytes, \
  52. .Buf.Out = __Buf, \
  53. .BusWidth = __BusWidth, \
  54. }
  55. #define SPI_MEM_OP_NO_DATA { }
  56. #define SPI_MEM_OP(__Cmd, __Addr, __Dummy, __Data) \
  57. { \
  58. .Cmd = __Cmd, \
  59. .Addr = __Addr, \
  60. .Dummy = __Dummy, \
  61. .Data = __Data, \
  62. }
  63. /**
  64. * Standard SPI NOR flash operations
  65. */
  66. #define SPINOR_RESET_OP \
  67. SPI_MEM_OP(SPI_MEM_OP_CMD(0xff, 1), \
  68. SPI_MEM_OP_NO_ADDR, \
  69. SPI_MEM_OP_NO_DUMMY, \
  70. SPI_MEM_OP_NO_DATA)
  71. #define SPINOR_WR_EN_DIS_OP(Enable) \
  72. SPI_MEM_OP(SPI_MEM_OP_CMD((Enable) ? 0x06 : 0x04, 1), \
  73. SPI_MEM_OP_NO_ADDR, \
  74. SPI_MEM_OP_NO_DUMMY, \
  75. SPI_MEM_OP_NO_DATA)
  76. #define SPINOR_READID_OP(NDummy, Buf, Len) \
  77. SPI_MEM_OP(SPI_MEM_OP_CMD(0x9f, 1), \
  78. SPI_MEM_OP_NO_ADDR, \
  79. SPI_MEM_OP_DUMMY(NDummy, 1), \
  80. SPI_MEM_OP_DATA_IN(Len, Buf, 1))
  81. #define SPINOR_SET_FEATURE_OP(reg, ValPtr) \
  82. SPI_MEM_OP(SPI_MEM_OP_CMD(0x1f, 1), \
  83. SPI_MEM_OP_ADDR(1, reg, 1), \
  84. SPI_MEM_OP_NO_DUMMY, \
  85. SPI_MEM_OP_DATA_OUT(1, ValPtr, 1))
  86. #define SPINOR_GET_FEATURE_OP(reg, ValPtr) \
  87. SPI_MEM_OP(SPI_MEM_OP_CMD(0x0f, 1), \
  88. SPI_MEM_OP_ADDR(1, reg, 1), \
  89. SPI_MEM_OP_NO_DUMMY, \
  90. SPI_MEM_OP_DATA_IN(1, ValPtr, 1))
  91. #define SPINOR_BLK_ERASE_OP(Addr) \
  92. SPI_MEM_OP(SPI_MEM_OP_CMD(0xd8, 1), \
  93. SPI_MEM_OP_ADDR(3, Addr, 1), \
  94. SPI_MEM_OP_NO_DUMMY, \
  95. SPI_MEM_OP_NO_DATA)
  96. #define SPINOR_PAGE_READ_OP(Addr) \
  97. SPI_MEM_OP(SPI_MEM_OP_CMD(0x13, 1), \
  98. SPI_MEM_OP_ADDR(3, Addr, 1), \
  99. SPI_MEM_OP_NO_DUMMY, \
  100. SPI_MEM_OP_NO_DATA)
  101. #define SPINOR_PAGE_READ_FROM_CACHE_OP(Fast, Addr, NDummy, Buf, Len) \
  102. SPI_MEM_OP(SPI_MEM_OP_CMD(Fast ? 0x0b : 0x03, 1), \
  103. SPI_MEM_OP_ADDR(2, Addr, 1), \
  104. SPI_MEM_OP_DUMMY(NDummy, 1), \
  105. SPI_MEM_OP_DATA_IN(Len, Buf, 1))
  106. #define SPINOR_PAGE_READ_FROM_CACHE_X2_OP(Addr, NDummy, Buf, Len) \
  107. SPI_MEM_OP(SPI_MEM_OP_CMD(0x3b, 1), \
  108. SPI_MEM_OP_ADDR(2, Addr, 1), \
  109. SPI_MEM_OP_DUMMY(NDummy, 1), \
  110. SPI_MEM_OP_DATA_IN(Len, Buf, 2))
  111. #define SPINOR_PAGE_READ_FROM_CACHE_X4_OP(Addr, NDummy, Buf, Len) \
  112. SPI_MEM_OP(SPI_MEM_OP_CMD(0x6b, 1), \
  113. SPI_MEM_OP_ADDR(2, Addr, 1), \
  114. SPI_MEM_OP_DUMMY(NDummy, 1), \
  115. SPI_MEM_OP_DATA_IN(Len, Buf, 4))
  116. #define SPINOR_PAGE_READ_FROM_CACHE_DUALIO_OP(Addr, NDummy, Buf, Len) \
  117. SPI_MEM_OP(SPI_MEM_OP_CMD(0xbb, 1), \
  118. SPI_MEM_OP_ADDR(2, Addr, 2), \
  119. SPI_MEM_OP_DUMMY(NDummy, 2), \
  120. SPI_MEM_OP_DATA_IN(Len, Buf, 2))
  121. #define SPINOR_PAGE_READ_FROM_CACHE_QUADIO_OP(Addr, NDummy, Buf, Len) \
  122. SPI_MEM_OP(SPI_MEM_OP_CMD(0xeb, 1), \
  123. SPI_MEM_OP_ADDR(2, Addr, 4), \
  124. SPI_MEM_OP_DUMMY(NDummy, 4), \
  125. SPI_MEM_OP_DATA_IN(Len, Buf, 4))
  126. #define SPINOR_PROG_EXEC_OP(Addr) \
  127. SPI_MEM_OP(SPI_MEM_OP_CMD(0x10, 1), \
  128. SPI_MEM_OP_ADDR(3, Addr, 1), \
  129. SPI_MEM_OP_NO_DUMMY, \
  130. SPI_MEM_OP_NO_DATA)
  131. #define SPINOR_PROG_LOAD(Reset, Addr, Buf, Len) \
  132. SPI_MEM_OP(SPI_MEM_OP_CMD(Reset ? 0x02 : 0x84, 1), \
  133. SPI_MEM_OP_ADDR(2, Addr, 1), \
  134. SPI_MEM_OP_NO_DUMMY, \
  135. SPI_MEM_OP_DATA_OUT(Len, Buf, 1))
  136. #define SPINOR_PROG_LOAD_X4(Reset, Addr, Buf, Len) \
  137. SPI_MEM_OP(SPI_MEM_OP_CMD(Reset ? 0x32 : 0x34, 1), \
  138. SPI_MEM_OP_ADDR(2, Addr, 1), \
  139. SPI_MEM_OP_NO_DUMMY, \
  140. SPI_MEM_OP_DATA_OUT(Len, Buf, 4))
  141. enum spi_mem_data_dir {
  142. SPI_MEM_NO_DATA,
  143. SPI_MEM_DATA_IN,
  144. SPI_MEM_DATA_OUT,
  145. };
  146. typedef struct {
  147. struct {
  148. UINT8 NBytes;
  149. UINT8 BusWidth;
  150. UINT8 Dtr : 1;
  151. UINT16 OpCode;
  152. } Cmd;
  153. struct {
  154. UINT8 NBytes;
  155. UINT8 BusWidth;
  156. UINT8 Dtr : 1;
  157. UINT64 Val;
  158. } Addr;
  159. struct {
  160. UINT8 NBytes;
  161. UINT8 BusWidth;
  162. UINT8 Dtr : 1;
  163. } Dummy;
  164. struct {
  165. UINT8 BusWidth;
  166. UINT8 Dtr : 1;
  167. enum spi_mem_data_dir Dir;
  168. UINT32 NBytes;
  169. union {
  170. VOID *In;
  171. CONST VOID *Out;
  172. } Buf;
  173. } Data;
  174. }SPI_MEM_OPS;
  175. typedef enum {
  176. SPI_MODE0, // CPOL = 0 & CPHA = 0
  177. SPI_MODE1, // CPOL = 0 & CPHA = 1
  178. SPI_MODE2, // CPOL = 1 & CPHA = 0
  179. SPI_MODE3 // CPOL = 1 & CPHA = 1
  180. } SPI_MODE;
  181. typedef struct {
  182. SPI_MODE Mode;
  183. UINT32 AddrSize;
  184. NOR_FLASH_INFO *Info;
  185. UINT32 RegBase;
  186. UINT32 MaxHz;
  187. UINT32 PrevHz;
  188. UINT32 CaliHz;
  189. INTN ReadDelay;
  190. UINT32 RefClkHz;
  191. UINT8 CaliCs;
  192. UINT8 IsDecodedCs;
  193. VOID* AhbBase;
  194. UINT32 AhbSize;
  195. UINT16 FifoDepth;
  196. UINT8 FifoWidth;
  197. UINT8 TrigAdd;
  198. BOOLEAN DacMode;
  199. UINT32 WRDelay;
  200. /* Flash parameters */
  201. UINT8 TshslNs;
  202. UINT8 Tsd2dNs;
  203. UINT8 TchshNs;
  204. UINT8 TslchNs;
  205. /* Transaction protocol parameters. */
  206. UINT8 InstWidth;
  207. UINT8 AddrWidth;
  208. UINT8 DataWidth;
  209. UINT8 Dtr;
  210. } SPI_DEVICE;
  211. typedef
  212. EFI_STATUS
  213. (EFIAPI *MV_SPI_INIT) (
  214. IN SPI_MASTER_PROTOCOL *This
  215. );
  216. typedef
  217. EFI_STATUS
  218. (EFIAPI *MV_SPI_TRANSFER) (
  219. IN SPI_DEVICE *Slave,
  220. IN SPI_MEM_OPS *op
  221. );
  222. typedef
  223. SPI_DEVICE *
  224. (EFIAPI *MV_SPI_SETUP_DEVICE) (
  225. IN SPI_MASTER_PROTOCOL *This,
  226. IN SPI_DEVICE *Slave,
  227. IN SPI_MODE Mode
  228. );
  229. typedef
  230. EFI_STATUS
  231. (EFIAPI *MV_SPI_FREE_DEVICE) (
  232. IN SPI_DEVICE *SpiDev
  233. );
  234. typedef
  235. EFI_STATUS
  236. (EFIAPI *MV_SPI_SET_SPEED) (
  237. IN SPI_DEVICE *Slave,
  238. IN UINT32 Hz
  239. );
  240. typedef
  241. EFI_STATUS
  242. (EFIAPI *MV_SPI_SET_MODE) (
  243. IN SPI_DEVICE *Slave,
  244. IN UINT8 Mode
  245. );
  246. struct _SPI_MASTER_PROTOCOL {
  247. MV_SPI_INIT Init;
  248. MV_SPI_TRANSFER Transfer;
  249. MV_SPI_SETUP_DEVICE SetupDevice;
  250. MV_SPI_FREE_DEVICE FreeDevice;
  251. MV_SPI_SET_SPEED SetSpeed;
  252. MV_SPI_SET_MODE SetMode;
  253. };
  254. #endif // __SPI_MASTER_PROTOCOL_H__