gpmi.h 15 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361
  1. /*
  2. * Copyright (c) 2012, Freescale Semiconductor, Inc.
  3. * All rights reserved.
  4. *
  5. * Redistribution and use in source and binary forms, with or without modification,
  6. * are permitted provided that the following conditions are met:
  7. *
  8. * o Redistributions of source code must retain the above copyright notice, this list
  9. * of conditions and the following disclaimer.
  10. *
  11. * o Redistributions in binary form must reproduce the above copyright notice, this
  12. * list of conditions and the following disclaimer in the documentation and/or
  13. * other materials provided with the distribution.
  14. *
  15. * o Neither the name of Freescale Semiconductor, Inc. nor the names of its
  16. * contributors may be used to endorse or promote products derived from this
  17. * software without specific prior written permission.
  18. *
  19. * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
  20. * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
  21. * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
  22. * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR
  23. * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
  24. * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
  25. * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
  26. * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
  27. * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
  28. * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  29. */
  30. #if !defined(__gpmi_h_)
  31. #define __gpmi_h_
  32. #include "sdk.h"
  33. #include "bch_ecc.h"
  34. /*!
  35. * @file gpmi.h
  36. * @brief The header file that contains the general definitions for NAND
  37. *
  38. * @ingroup diag_nand
  39. */
  40. //! @addtogroup diag_nand
  41. //! @{
  42. #pragma pack(1)
  43. //! @brief NAND timings for setting up the GPMI timing.
  44. //!
  45. //! This structure holds the timings for the NAND. This data is used by
  46. //! gpmi_set_timings() to setup the GPMI hardware registers.
  47. typedef struct GpmiNandTimings
  48. {
  49. //! @brief The data setup time (tDS), in nanoseconds.
  50. uint8_t tDS;
  51. //! @brief The data hold time (tDH), in nanoseconds.
  52. uint8_t tDH;
  53. //! @brief The address setup time (tSU), in nanoseconds.
  54. //!
  55. //! This value amalgamates the NAND parameters tCLS, tCS, and tALS.
  56. uint8_t tSU;
  57. //! @brief From the NAND datasheet.
  58. uint8_t tREA;
  59. //! @brief From the NAND datasheet.
  60. //!
  61. //! This is the amount of time that the last contents of the data lines will persist
  62. //! after the controller drives the -RE signal true.
  63. //!
  64. //! EDO Mode: This time is from the NAND spec, and the persistence of data
  65. //! is determined by (tRLOH + tDH).
  66. //!
  67. //! Non-EDO Mode: This time is ignored, because the persistence of data
  68. //! is determined by tRHOH.
  69. uint8_t tRLOH;
  70. //! @brief From the NAND datasheet.
  71. //!
  72. //! This is the amount of time that the last contents of the data lines will persist after the
  73. //! controller drives the -RE signal false.
  74. //!
  75. //! EDO Mode: This time is ignored, because the persistence of data is determined by
  76. //! (tRLOH + tDH).
  77. //!
  78. //! Non-EDO Mode: This time is totally due to capacitive effects of the hardware. For reliable
  79. //! behavior it should be set to zero, unless there is specific knowledge of the trace
  80. //! capacitance and the persistence of the data values.
  81. uint8_t tRHOH;
  82. } GpmiNandTimings_t;
  83. #pragma pack()
  84. // Forward declaration.
  85. typedef struct _apbh_dma_t apbh_dma_t;
  86. //! @brief DMA wait options.
  87. //!
  88. //! These mask values are combined together to form the wait mask that is passed to gpmi_run_dma().
  89. //! The wait mask indicates which IRQs must fire before the DMA is considered done executing.
  90. enum _nand_gpmi_dma_wait_mask {
  91. kNandGpmiDmaWaitMask_Nothing = 0, //!< Do not wait.
  92. kNandGpmiDmaWaitMask_GpmiDma = 1, //!< Wait for the APBH DMA completion IRQ.
  93. kNandGpmiDmaWaitMask_Ecc = 2, //!< Wait for the BCH completion IRQ.
  94. };
  95. //! @brief APBH DMA channel for GPMI chip select 0.
  96. #define NAND0_APBH_CH (0)
  97. //! @brief Number of NAND chip selects supported by this chip.
  98. //!
  99. //! This is also implicitly the number of DMA channels in the APBH.
  100. #define GPMI_CHIP_SELECT_COUNT (4)
  101. //! @name Error codes
  102. //@{
  103. #if !defined(SUCCESS)
  104. #define SUCCESS (0)
  105. #endif
  106. #define ERROR_DDI_NAND_GPMI_NOT_PRESENT (1)
  107. #define ERROR_DDI_NAND_GPMI_DMA_TIMEOUT (2)
  108. #define ERROR_DDI_NAND_GPMI_DMA_BUSY (3)
  109. #define ERROR_DDI_NAND_GPMI_UNCORRECTABLE_ECC (4)
  110. #define ERROR_DDI_NAND_HAL_WRITE_FAILED (5)
  111. //@}
  112. ////////////////////////////////////////////////////////////////////////////////
  113. // Prototypes
  114. ////////////////////////////////////////////////////////////////////////////////
  115. #ifdef __cplusplus
  116. extern "C" {
  117. #endif
  118. //! @name Init and shutdown
  119. //@{
  120. ////////////////////////////////////////////////////////////////////////////////
  121. //! @brief Enable and initialize the GPMI driver.
  122. //!
  123. //! This function configures the GPMI block using the HW registers based upon
  124. //! the desired chip and the number of bits. You must call this API for each
  125. //! chip select that will be used in the application configuration.
  126. //!
  127. //! @param[in] minDelay Minimum signal propagation delay in nanoseconds. Pass 0 to use the
  128. //! default of 5 ns.
  129. //! @param[in] maxDelay Maximum signal propagation delay in nanoseconds. Pass 0 to use the
  130. //! default of 9 ns.
  131. //!
  132. //! @return SUCCESS
  133. //! @return ERROR_DDI_NAND_GPMI_NOT_PRESENT
  134. ////////////////////////////////////////////////////////////////////////////////
  135. int gpmi_init(uint32_t minDelay, uint32_t maxDelay);
  136. ////////////////////////////////////////////////////////////////////////////////
  137. //! @brief Resets the GPMI block.
  138. //!
  139. //! A soft reset can take multiple clocks to complete, so do NOT gate the
  140. //! clock when setting soft reset. The reset process will gate the clock
  141. //! automatically. Poll until this has happened before subsequently
  142. //! clearing soft reset and clock gate.
  143. ////////////////////////////////////////////////////////////////////////////////
  144. void gpmi_soft_reset(void);
  145. ////////////////////////////////////////////////////////////////////////////////
  146. //! @brief Disable the GPMI driver.
  147. //!
  148. //! This function gates the clock to the GPMI peripheral.
  149. ////////////////////////////////////////////////////////////////////////////////
  150. void gpmi_disable(void);
  151. //@}
  152. //! @name Write enable
  153. //@{
  154. ////////////////////////////////////////////////////////////////////////////////
  155. //! @brief Enable writes via the Write Protect line of the NAND.
  156. //!
  157. //! Enable or disable writes via the /WP pin of the NAND. This WP line is
  158. //! shared amongst all the NANDs.
  159. //!
  160. //! @param[in] doEnable Enable writes (1) or Disable writes (0) (/WP pin)
  161. ////////////////////////////////////////////////////////////////////////////////
  162. void gpmi_enable_writes(bool doEnable);
  163. //@}
  164. //! @name DMA Utilities
  165. //@{
  166. ////////////////////////////////////////////////////////////////////////////////
  167. //! @brief Synchronously execute a DMA descriptor chain.
  168. //!
  169. //! Starts a NAND DMA command associated with the chip select
  170. //! in the @a chipSelect parameter. Once the DMA is running, this function waits
  171. //! for the interrupt handler(s) to signal completion.
  172. //!
  173. //! @param[in] theDma Pointer to dma command structure. Must be the virtual address,
  174. //! as it is converted to a physical address before the DMA is started.
  175. //! @param[in] chipSelect Which NAND chip select should be started.
  176. //! @param[in] waitMask A bitmask used to indicate criteria for terminating the DMA.
  177. //! See #_nand_gpmi_dma_wait_mask for more info.
  178. //! @param[in] timeout Number of microseconds to wait before timing out. If
  179. //! zero is passed for the timeout, then this function will wait forever.
  180. //!
  181. //! @retval SUCCESS The DMA is started.
  182. //! @retval ERROR_DDI_NAND_GPMI_DMA_BUSY Another DMA is already running.
  183. //! @retval ERROR_DDI_NAND_GPMI_DMA_TIMEOUT DMA never completed or is still
  184. //! running. This value is returned explicitly from this function when
  185. //! the DMA semphore times out, and most DMA chains also return this
  186. //! error (see below for how) when the GPMI device busy timeout expires.
  187. //!
  188. //! @note Uses the BAR field of the last DMA command to signal
  189. //! result of the DMA chain.
  190. ////////////////////////////////////////////////////////////////////////////////
  191. int gpmi_run_dma(apbh_dma_t * theDma, unsigned chipSelect, uint16_t waitMask, uint32_t timeout);
  192. ////////////////////////////////////////////////////////////////////////////////
  193. //! @brief Returns a Boolean indicating if a DMA is currently running.
  194. //!
  195. //! @param u32NANDDeviceNum Specifies which DMA channel to inspect.
  196. //! @retval true A DMA is currently running.
  197. //! @retval false The DMA channel is free.
  198. ////////////////////////////////////////////////////////////////////////////////
  199. bool gpmi_is_dma_active(uint32_t u32NANDDeviceNum);
  200. //@}
  201. //! @name Timing Control Functions
  202. //@{
  203. ////////////////////////////////////////////////////////////////////////////////
  204. //! @brief Fill the given timing structure with the safe timings.
  205. //!
  206. //! This function is used to get the timings characteristics that work with
  207. //! every device we've ever known. These timings should be used during initialization
  208. //! and device discovery. Once the device type is known, timings specific to
  209. //! that device should be set. Remember to actually set the safe timings once
  210. //! you get them by calling ddi_gpmi_set_timings().
  211. //!
  212. //! @param[out] timings The timings structure that will be set to the safe
  213. //! timings upon return.
  214. ////////////////////////////////////////////////////////////////////////////////
  215. void gpmi_get_safe_timings(GpmiNandTimings_t * timings);
  216. ////////////////////////////////////////////////////////////////////////////////
  217. //! @brief Set the flash timing for optimal NAND performance.
  218. //!
  219. //! Set the optimal NAND timings based upon the passed in NAND timings and the
  220. //! current GPMI clock.
  221. //!
  222. //! @param[in] newTimings Pointer to timing table for the NAND.
  223. //!
  224. //! @warning This function assumes all NAND I/O is halted.
  225. ////////////////////////////////////////////////////////////////////////////////
  226. void gpmi_set_timings(const GpmiNandTimings_t * newTimings);
  227. ////////////////////////////////////////////////////////////////////////////////
  228. //! @brief Set the timeout value for wait for ready.
  229. //!
  230. //! The timeout value set here is used for the GPMI wait for ready mode. It
  231. //! will have the most effect upon DMA operations.
  232. //!
  233. //! @param[in] busyTimeout Timeout value in microseconds.
  234. ////////////////////////////////////////////////////////////////////////////////
  235. void gpmi_set_busy_timeout(uint32_t busyTimeout);
  236. ////////////////////////////////////////////////////////////////////////////////
  237. //! @brief Returns the current GPMI timings values.
  238. //!
  239. //! @return A pointer to the current timing values used by the GPMI block.
  240. //! This will be the last set of timings passed to gpmi_set_timings().
  241. ////////////////////////////////////////////////////////////////////////////////
  242. const GpmiNandTimings_t * gpmi_get_current_timings();
  243. //@}
  244. //! @name Common NAND operations
  245. //!
  246. //! These functions are used to perform the common set of NAND read and write operations. They
  247. //! will build an appropriate DMA chain and execute it synchronously.
  248. //@{
  249. ////////////////////////////////////////////////////////////////////////////////
  250. //! @brief Configure the driver for a particular NAND type.
  251. ////////////////////////////////////////////////////////////////////////////////
  252. int gpmi_nand_configure(unsigned rowBytes, unsigned columnBytes, unsigned pagesPerBlock, const BchEccLayout_t * ecc);
  253. ////////////////////////////////////////////////////////////////////////////////
  254. //! @brief Reset the NAND.
  255. ////////////////////////////////////////////////////////////////////////////////
  256. int gpmi_nand_reset(unsigned chipSelect);
  257. ////////////////////////////////////////////////////////////////////////////////
  258. //! @brief Read a NAND's ID.
  259. ////////////////////////////////////////////////////////////////////////////////
  260. int gpmi_nand_read_id(unsigned chipSelect, uint8_t * resultID);
  261. ////////////////////////////////////////////////////////////////////////////////
  262. //! @brief Erase a block on a NAND.
  263. ////////////////////////////////////////////////////////////////////////////////
  264. int gpmi_nand_erase_block(unsigned chipSelect, uint32_t blockNumber);
  265. ////////////////////////////////////////////////////////////////////////////////
  266. //! @brief Read raw bytes from a NAND page.
  267. ////////////////////////////////////////////////////////////////////////////////
  268. int gpmi_nand_read_raw(unsigned chipSelect, uint32_t pageNumber, uint8_t * buffer, uint32_t offset, uint32_t count);
  269. ////////////////////////////////////////////////////////////////////////////////
  270. //! @brief Write a NAND page without using ECC.
  271. ////////////////////////////////////////////////////////////////////////////////
  272. int gpmi_nand_write_raw(unsigned chipSelect, uint32_t pageNumber, const uint8_t * buffer, uint32_t offset, uint32_t count);
  273. ////////////////////////////////////////////////////////////////////////////////
  274. //! @brief Read a NAND page using ECC.
  275. //! @bug Not yet functional.
  276. ////////////////////////////////////////////////////////////////////////////////
  277. int gpmi_nand_read_page(unsigned chipSelect, uint32_t pageNumber, uint8_t * buffer, uint8_t * auxBuffer);
  278. ////////////////////////////////////////////////////////////////////////////////
  279. //! @brief Read the metadata from a NAND page.
  280. //! @bug Not yet functional.
  281. ////////////////////////////////////////////////////////////////////////////////
  282. int gpmi_nand_read_metadata(unsigned chipSelect, uint32_t pageNumber, uint8_t * buffer);
  283. ////////////////////////////////////////////////////////////////////////////////
  284. //! @brief Write a NAND page.
  285. //! @bug Not yet functional.
  286. ////////////////////////////////////////////////////////////////////////////////
  287. int gpmi_nand_write_page(unsigned chipSelect, uint32_t pageNumber, const uint8_t * buffer, const uint8_t * auxBuffer);
  288. //@}
  289. //! @name Application APIs
  290. //!
  291. //! These functions must be implemented by the application. They are intended to isolate the
  292. //! GPMI driver from board and application specific design choices.
  293. //@{
  294. //! @brief Configure GPMI pins.
  295. void gpmi_iomux_config(void);
  296. //! @brief External function to enable and configure the GPMI clock.
  297. void gpmi_nand_clk_setup(void);
  298. //! @brief Convert a virtual address to a physical address.
  299. static inline void * nand_virtual_to_physical(const void * virtualAddress) { return (void *)virtualAddress; }
  300. //@}
  301. #ifdef __cplusplus
  302. }
  303. #endif
  304. //! @}
  305. #endif //__gpmi_h_
  306. ////////////////////////////////////////////////////////////////////////////////
  307. // EOF
  308. ////////////////////////////////////////////////////////////////////////////////