fsl_qspi.c 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383
  1. /*
  2. * The Clear BSD License
  3. * Copyright (c) 2015, Freescale Semiconductor, Inc.
  4. * Copyright 2016-2017 NXP
  5. * All rights reserved.
  6. *
  7. * Redistribution and use in source and binary forms, with or without modification,
  8. * are permitted (subject to the limitations in the disclaimer below) provided
  9. * that the following conditions are met:
  10. *
  11. * o Redistributions of source code must retain the above copyright notice, this list
  12. * of conditions and the following disclaimer.
  13. *
  14. * o Redistributions in binary form must reproduce the above copyright notice, this
  15. * list of conditions and the following disclaimer in the documentation and/or
  16. * other materials provided with the distribution.
  17. *
  18. * o Neither the name of the copyright holder nor the names of its
  19. * contributors may be used to endorse or promote products derived from this
  20. * software without specific prior written permission.
  21. *
  22. * NO EXPRESS OR IMPLIED LICENSES TO ANY PARTY'S PATENT RIGHTS ARE GRANTED BY THIS LICENSE.
  23. * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
  24. * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
  25. * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
  26. * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR
  27. * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
  28. * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
  29. * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
  30. * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
  31. * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
  32. * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  33. */
  34. #include "fsl_qspi.h"
  35. /* Component ID definition, used by tools. */
  36. #ifndef FSL_COMPONENT_ID
  37. #define FSL_COMPONENT_ID "platform.drivers.qspi"
  38. #endif
  39. /*******************************************************************************
  40. * Definitations
  41. ******************************************************************************/
  42. enum _qspi_transfer_state
  43. {
  44. kQSPI_TxBusy = 0x0U, /*!< QSPI is busy */
  45. kQSPI_TxIdle, /*!< Transfer is done. */
  46. kQSPI_TxError /*!< Transfer error occured. */
  47. };
  48. #define QSPI_AHB_BUFFER_REG(base, index) (((volatile uint32_t *)&((base)->BUF0CR))[(index)])
  49. /*******************************************************************************
  50. * Prototypes
  51. ******************************************************************************/
  52. /*******************************************************************************
  53. * Variables
  54. ******************************************************************************/
  55. /* Base pointer array */
  56. static QuadSPI_Type *const s_qspiBases[] = QuadSPI_BASE_PTRS;
  57. #if !(defined(FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) && FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL)
  58. /* Clock name array */
  59. static const clock_ip_name_t s_qspiClock[] = QSPI_CLOCKS;
  60. #endif /* FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL */
  61. /*******************************************************************************
  62. * Code
  63. ******************************************************************************/
  64. uint32_t QSPI_GetInstance(QuadSPI_Type *base)
  65. {
  66. uint32_t instance;
  67. /* Find the instance index from base address mappings. */
  68. for (instance = 0; instance < ARRAY_SIZE(s_qspiBases); instance++)
  69. {
  70. if (s_qspiBases[instance] == base)
  71. {
  72. break;
  73. }
  74. }
  75. assert(instance < ARRAY_SIZE(s_qspiBases));
  76. return instance;
  77. }
  78. void QSPI_Init(QuadSPI_Type *base, qspi_config_t *config, uint32_t srcClock_Hz)
  79. {
  80. uint32_t i = 0;
  81. uint32_t val = 0;
  82. #if !(defined(FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) && FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL)
  83. /* Enable QSPI clock */
  84. CLOCK_EnableClock(s_qspiClock[QSPI_GetInstance(base)]);
  85. #endif /* FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL */
  86. /* Do software reset to QSPI module */
  87. QSPI_SoftwareReset(base);
  88. /* Clear the FIFO region */
  89. QSPI_ClearFifo(base, kQSPI_AllFifo);
  90. /* Configure QSPI */
  91. QSPI_Enable(base, false);
  92. #if !defined (FSL_FEATURE_QSPI_CLOCK_CONTROL_EXTERNAL) || (!FSL_FEATURE_QSPI_CLOCK_CONTROL_EXTERNAL)
  93. /* Set qspi clock source */
  94. base->SOCCR = config->clockSource;
  95. /* Set the divider of QSPI clock */
  96. base->MCR &= ~QuadSPI_MCR_SCLKCFG_MASK;
  97. base->MCR |= QuadSPI_MCR_SCLKCFG(srcClock_Hz / config->baudRate - 1U);
  98. #endif /* FSL_FEATURE_QSPI_CLOCK_CONTROL_EXTERNAL */
  99. /* Set AHB buffer size and buffer master */
  100. for (i = 0; i < FSL_FEATURE_QSPI_AHB_BUFFER_COUNT; i++)
  101. {
  102. val = QuadSPI_BUF0CR_MSTRID(config->AHBbufferMaster[i]) | QuadSPI_BUF0CR_ADATSZ(config->AHBbufferSize[i] / 8U);
  103. QSPI_AHB_BUFFER_REG(base, i) = val;
  104. }
  105. if (config->enableAHBbuffer3AllMaster)
  106. {
  107. base->BUF3CR |= QuadSPI_BUF3CR_ALLMST_MASK;
  108. }
  109. else
  110. {
  111. base->BUF3CR &= ~QuadSPI_BUF3CR_ALLMST_MASK;
  112. }
  113. /* Set watermark */
  114. base->RBCT &= ~QuadSPI_RBCT_WMRK_MASK;
  115. base->RBCT |= QuadSPI_RBCT_WMRK(config->rxWatermark - 1);
  116. #if !defined (FSL_FEATURE_QSPI_HAS_NO_TXDMA) || (!FSL_FEATURE_QSPI_HAS_NO_TXDMA)
  117. base->TBCT &= ~QuadSPI_TBCT_WMRK_MASK;
  118. base->TBCT |= QuadSPI_TBCT_WMRK(config->txWatermark - 1);
  119. #endif /* FSL_FEATURE_QSPI_HAS_NO_TXDMA */
  120. /* Enable QSPI module */
  121. if (config->enableQspi)
  122. {
  123. QSPI_Enable(base, true);
  124. }
  125. }
  126. void QSPI_GetDefaultQspiConfig(qspi_config_t *config)
  127. {
  128. config->clockSource = 2U;
  129. config->baudRate = 24000000U;
  130. config->AHBbufferMaster[0] = 0xE;
  131. config->AHBbufferMaster[1] = 0xE;
  132. config->AHBbufferMaster[2] = 0xE;
  133. config->enableAHBbuffer3AllMaster = true;
  134. config->txWatermark = 8;
  135. config->rxWatermark = 8;
  136. config->enableQspi = true;
  137. }
  138. void QSPI_Deinit(QuadSPI_Type *base)
  139. {
  140. QSPI_Enable(base, false);
  141. #if !(defined(FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) && FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL)
  142. CLOCK_DisableClock(s_qspiClock[QSPI_GetInstance(base)]);
  143. #endif /* FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL */
  144. }
  145. void QSPI_SetFlashConfig(QuadSPI_Type *base, qspi_flash_config_t *config)
  146. {
  147. uint32_t address = FSL_FEATURE_QSPI_AMBA_BASE + config->flashA1Size;
  148. uint32_t val = 0;
  149. uint32_t i = 0;
  150. /* Disable module */
  151. QSPI_Enable(base, false);
  152. /* Config the serial flash size */
  153. base->SFA1AD = address;
  154. address += config->flashA2Size;
  155. base->SFA2AD = address;
  156. #if defined(FSL_FEATURE_QSPI_SUPPORT_PARALLEL_MODE) && (FSL_FEATURE_QSPI_SUPPORT_PARALLEL_MODE)
  157. address += config->flashB1Size;
  158. base->SFB1AD = address;
  159. address += config->flashB2Size;
  160. base->SFB2AD = address;
  161. #endif /* FSL_FEATURE_QSPI_SUPPORT_PARALLEL_MODE */
  162. #if !defined (FSL_FEATURE_QSPI_HAS_NO_SFACR) || (!FSL_FEATURE_QSPI_HAS_NO_SFACR)
  163. /* Set Word Addressable feature */
  164. val = QuadSPI_SFACR_WA(config->enableWordAddress) | QuadSPI_SFACR_CAS(config->cloumnspace);
  165. base->SFACR = val;
  166. #endif /* FSL_FEATURE_QSPI_HAS_NO_SFACR */
  167. /* Config look up table */
  168. base->LUTKEY = 0x5AF05AF0U;
  169. base->LCKCR = 0x2U;
  170. for (i = 0; i < FSL_FEATURE_QSPI_LUT_DEPTH; i++)
  171. {
  172. base->LUT[i] = config->lookuptable[i];
  173. }
  174. base->LUTKEY = 0x5AF05AF0U;
  175. base->LCKCR = 0x1U;
  176. #if !defined (FSL_FEATURE_QSPI_HAS_NO_TDH) || (!FSL_FEATURE_QSPI_HAS_NO_TDH)
  177. /* Config flash timing */
  178. val = QuadSPI_FLSHCR_TCSS(config->CSHoldTime) | QuadSPI_FLSHCR_TDH(config->dataHoldTime) |
  179. QuadSPI_FLSHCR_TCSH(config->CSSetupTime);
  180. #else
  181. val = QuadSPI_FLSHCR_TCSS(config->CSHoldTime) | QuadSPI_FLSHCR_TCSH(config->CSSetupTime);
  182. #endif /* FSL_FEATURE_QSPI_HAS_NO_TDH */
  183. base->FLSHCR = val;
  184. /* Set flash endianness */
  185. base->MCR &= ~QuadSPI_MCR_END_CFG_MASK;
  186. base->MCR |= QuadSPI_MCR_END_CFG(config->endian);
  187. /* Enable QSPI again */
  188. QSPI_Enable(base, true);
  189. }
  190. void QSPI_SoftwareReset(QuadSPI_Type *base)
  191. {
  192. uint32_t i = 0;
  193. /* Reset AHB domain and buffer domian */
  194. base->MCR |= (QuadSPI_MCR_SWRSTHD_MASK | QuadSPI_MCR_SWRSTSD_MASK);
  195. /* Wait several time for the reset to finish, this method came from IC team */
  196. for (i = 0; i < 100; i++)
  197. {
  198. __ASM("nop");
  199. }
  200. /* Disable QSPI module */
  201. QSPI_Enable(base, false);
  202. /* Clear the reset flags */
  203. base->MCR &= ~(QuadSPI_MCR_SWRSTHD_MASK | QuadSPI_MCR_SWRSTSD_MASK);
  204. /* Enable QSPI module */
  205. QSPI_Enable(base, true);
  206. }
  207. uint32_t QSPI_GetRxDataRegisterAddress(QuadSPI_Type *base)
  208. {
  209. /* From RDBR */
  210. if (base->RBCT & QuadSPI_RBCT_RXBRD_MASK)
  211. {
  212. return (uint32_t)(&(base->RBDR[0]));
  213. }
  214. else
  215. {
  216. /* From ARDB */
  217. return FSL_FEATURE_QSPI_ARDB_BASE;
  218. }
  219. }
  220. void QSPI_ExecuteIPCommand(QuadSPI_Type *base, uint32_t index)
  221. {
  222. while (QSPI_GetStatusFlags(base) & (kQSPI_Busy | kQSPI_IPAccess))
  223. {
  224. }
  225. QSPI_ClearCommandSequence(base, kQSPI_IPSeq);
  226. /* Write the seqid bit */
  227. base->IPCR = ((base->IPCR & (~QuadSPI_IPCR_SEQID_MASK)) | QuadSPI_IPCR_SEQID(index / 4U));
  228. }
  229. void QSPI_ExecuteAHBCommand(QuadSPI_Type *base, uint32_t index)
  230. {
  231. while (QSPI_GetStatusFlags(base) & (kQSPI_Busy | kQSPI_AHBAccess))
  232. {
  233. }
  234. QSPI_ClearCommandSequence(base, kQSPI_BufferSeq);
  235. base->BFGENCR = ((base->BFGENCR & (~QuadSPI_BFGENCR_SEQID_MASK)) | QuadSPI_BFGENCR_SEQID(index / 4U));
  236. }
  237. void QSPI_UpdateLUT(QuadSPI_Type *base, uint32_t index, uint32_t *cmd)
  238. {
  239. uint8_t i = 0;
  240. /* Unlock the LUT */
  241. base->LUTKEY = 0x5AF05AF0U;
  242. base->LCKCR = 0x2U;
  243. /* Write data into LUT */
  244. for (i = 0; i < 4; i++)
  245. {
  246. base->LUT[index + i] = *cmd;
  247. cmd++;
  248. }
  249. /* Lcok LUT again */
  250. base->LUTKEY = 0x5AF05AF0U;
  251. base->LCKCR = 0x1U;
  252. }
  253. void QSPI_SetReadDataArea(QuadSPI_Type *base, qspi_read_area_t area)
  254. {
  255. base->RBCT &= ~QuadSPI_RBCT_RXBRD_MASK;
  256. base->RBCT |= QuadSPI_RBCT_RXBRD(area);
  257. }
  258. uint32_t QSPI_ReadData(QuadSPI_Type *base)
  259. {
  260. if (base->RBCT & QuadSPI_RBCT_RXBRD_MASK)
  261. {
  262. return base->RBDR[0];
  263. }
  264. else
  265. {
  266. /* Data from ARDB. */
  267. return *((uint32_t *)FSL_FEATURE_QSPI_ARDB_BASE);
  268. }
  269. }
  270. void QSPI_WriteBlocking(QuadSPI_Type *base, uint32_t *buffer, size_t size)
  271. {
  272. assert(size >= 16U);
  273. uint32_t i = 0;
  274. for (i = 0; i < size / 4U; i++)
  275. {
  276. /* Check if the buffer is full */
  277. while (QSPI_GetStatusFlags(base) & kQSPI_TxBufferFull)
  278. {
  279. }
  280. QSPI_WriteData(base, *buffer);
  281. buffer++;
  282. }
  283. }
  284. void QSPI_ReadBlocking(QuadSPI_Type *base, uint32_t *buffer, size_t size)
  285. {
  286. uint32_t i = 0;
  287. uint32_t j = 0;
  288. uint32_t temp = 0;
  289. uint32_t level = (base->RBCT & QuadSPI_RBCT_WMRK_MASK) + 1U;
  290. while (i < size / 4)
  291. {
  292. /* Check if there is data */
  293. if ((size / 4 - i) < level)
  294. {
  295. do
  296. {
  297. temp = (base->RBSR & QuadSPI_RBSR_RDBFL_MASK) >> QuadSPI_RBSR_RDBFL_SHIFT;
  298. } while (!temp);
  299. }
  300. else
  301. {
  302. while ((QSPI_GetStatusFlags(base) & kQSPI_RxWatermark) == 0U)
  303. {
  304. }
  305. }
  306. level = (level < (size / 4 - i)) ? level : (size / 4 - i);
  307. /* Data from RBDR */
  308. if (base->RBCT & QuadSPI_RBCT_RXBRD_MASK)
  309. {
  310. for (j = 0; j < level; j++)
  311. {
  312. buffer[i + j] = base->RBDR[j];
  313. }
  314. }
  315. else
  316. {
  317. /* Data from ARDB. */
  318. for (j = 0; j < level; j++)
  319. {
  320. buffer[i + j] = ((uint32_t *)FSL_FEATURE_QSPI_ARDB_BASE)[j];
  321. }
  322. }
  323. i += level;
  324. /* Clear the Buffer */
  325. QSPI_ClearErrorFlag(base, kQSPI_RxBufferDrain);
  326. }
  327. }