drv_pdma.h 10 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332
  1. /* Copyright (c) 2023, Canaan Bright Sight Co., Ltd
  2. *
  3. * Redistribution and use in source and binary forms, with or without
  4. * modification, are permitted provided that the following conditions are met:
  5. * 1. Redistributions of source code must retain the above copyright
  6. * notice, this list of conditions and the following disclaimer.
  7. * 2. Redistributions in binary form must reproduce the above copyright
  8. * notice, this list of conditions and the following disclaimer in the
  9. * documentation and/or other materials provided with the distribution.
  10. *
  11. * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND
  12. * CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
  13. * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
  14. * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
  15. * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
  16. * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
  17. * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
  18. * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
  19. * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
  20. * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
  21. * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
  22. * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
  23. * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  24. */
  25. /*
  26. * Copyright (c) 2006-2025 RT-Thread Development Team
  27. *
  28. * SPDX-License-Identifier: Apache-2.0
  29. */
  30. #ifndef DRV_PDMA_H_
  31. #define DRV_PDMA_H_
  32. #include <rtdef.h>
  33. #include "board.h"
  34. /**
  35. * @brief PDMA channel enumeration
  36. */
  37. typedef enum pdma_ch {
  38. PDMA_CH_0 = 0, /**< Channel 0 */
  39. PDMA_CH_1 = 1, /**< Channel 1 */
  40. PDMA_CH_2 = 2, /**< Channel 2 */
  41. PDMA_CH_3 = 3, /**< Channel 3 */
  42. PDMA_CH_4 = 4, /**< Channel 4 */
  43. PDMA_CH_5 = 5, /**< Channel 5 */
  44. PDMA_CH_6 = 6, /**< Channel 6 */
  45. PDMA_CH_7 = 7, /**< Channel 7 */
  46. PDMA_CH_MAX, /**< Maximum channel count */
  47. } pdma_ch_e;
  48. /* PDMA Register Access Macros */
  49. #define pdma_write32(addr, val) writel((val), (volatile void *)(addr))
  50. #define pdma_read32(addr) readl((volatile void *)(addr))
  51. /* PDMA Configuration Constants */
  52. #define PDMA_MAX_WAIT_MS 2000 /* Maximum wait time in milliseconds */
  53. #define PDMA_MAX_LINE_SIZE 64 /* Maximum data block size per transfer */
  54. /**
  55. * @brief PDMA Interrupt Mask Definitions
  56. *
  57. * These macros define the bitmask values for different PDMA interrupt types.
  58. * Each interrupt type is represented by a unique bit in the interrupt status register.
  59. */
  60. #define PDMA_PDONE_INT 0x00000001 /**< Transfer Done interrupt mask */
  61. #define PDMA_PITEM_INT 0x00000100 /**< Item Done interrupt mask */
  62. #define PDMA_PPAUSE_INT 0x00010000 /**< Transfer Paused interrupt mask */
  63. #define PDMA_PTOUT_INT 0x01000000 /**< Transfer Timeout interrupt mask */
  64. /* Combined interrupt masks */
  65. #define PDMA_ALL_INTS (PDMA_PDONE_INT | PDMA_PITEM_INT | PDMA_PPAUSE_INT | PDMA_PTOUT_INT) /**< All PDMA interrupts mask */
  66. /**
  67. * @brief PDMA channel interrupt numbers
  68. */
  69. #define PDMA_CHANNEL0_IRQn K230_IRQ_PDMA /**< Channel 0 IRQ number */
  70. #define PDMA_CHANNEL1_IRQn K230_IRQ_PDMA_CHANNEL1 /**< Channel 1 IRQ number */
  71. #define PDMA_CHANNEL2_IRQn K230_IRQ_PDMA_CHANNEL2 /**< Channel 2 IRQ number */
  72. #define PDMA_CHANNEL3_IRQn K230_IRQ_PDMA_CHANNEL3 /**< Channel 3 IRQ number */
  73. #define PDMA_CHANNEL4_IRQn K230_IRQ_PDMA_CHANNEL4 /**< Channel 4 IRQ number */
  74. #define PDMA_CHANNEL5_IRQn K230_IRQ_PDMA_CHANNEL5 /**< Channel 5 IRQ number */
  75. #define PDMA_CHANNEL6_IRQn K230_IRQ_PDMA_CHANNEL6 /**< Channel 6 IRQ number */
  76. #define PDMA_CHANNEL7_IRQn K230_IRQ_PDMA_CHANNEL7 /**< Channel 7 IRQ number */
  77. /**
  78. * @brief PDMA channel state enumeration
  79. */
  80. typedef enum {
  81. PDMA_STATE_BUSY = 0x1, /**< Channel is busy transferring */
  82. PDMA_STATE_PAUSE = 0x2, /**< Channel is paused */
  83. } pdma_state_e;
  84. /**
  85. * @brief PDMA control command enumeration
  86. */
  87. typedef enum {
  88. PDMA_CMD_START = 0x1, /**< Start DMA transfer command */
  89. PDMA_CMD_STOP = 0x2, /**< Stop DMA transfer command */
  90. PDMA_CMD_RESUME = 0x4, /**< Resume paused transfer command */
  91. } pdma_cmd_e;
  92. /**
  93. * @brief PDMA data transfer direction enumeration
  94. *
  95. * @param TX Transmit direction: Data flows from system memory to peripheral device
  96. * @param RX Receive direction: Data flows from peripheral device to system memory
  97. */
  98. typedef enum pdma_rxtx {
  99. TX = 0,
  100. RX = 1,
  101. } pdma_rxtx_e;
  102. /**
  103. * @brief PDMA burst length configuration
  104. */
  105. typedef enum pdma_burst_len {
  106. PBURST_LEN_1 = 0,
  107. PBURST_LEN_2 = 1,
  108. PBURST_LEN_3 = 2,
  109. PBURST_LEN_4 = 3,
  110. PBURST_LEN_5 = 4,
  111. PBURST_LEN_6 = 5,
  112. PBURST_LEN_7 = 6,
  113. PBURST_LEN_8 = 7,
  114. PBURST_LEN_9 = 8,
  115. PBURST_LEN_10 = 9,
  116. PBURST_LEN_11 = 10,
  117. PBURST_LEN_12 = 11,
  118. PBURST_LEN_13 = 12,
  119. PBURST_LEN_14 = 13,
  120. PBURST_LEN_15 = 14,
  121. PBURST_LEN_16 = 15,
  122. } pdma_burst_len_e;
  123. /**
  124. * @brief Peripheral device selection for PDMA
  125. */
  126. typedef enum device_sel {
  127. UART0_TX = 0,
  128. UART0_RX = 1,
  129. UART1_TX = 2,
  130. UART1_RX = 3,
  131. UART2_TX = 4,
  132. UART2_RX = 5,
  133. UART3_TX = 6,
  134. UART3_RX = 7,
  135. UART4_TX = 8,
  136. UART4_RX = 9,
  137. I2C0_TX = 10,
  138. I2C0_RX = 11,
  139. I2C1_TX = 12,
  140. I2C1_RX = 13,
  141. I2C2_TX = 14,
  142. I2C2_RX = 15,
  143. I2C3_TX = 16,
  144. I2C3_RX = 17,
  145. I2C4_TX = 18,
  146. I2C4_RX = 19,
  147. AUDIO_TX = 20,
  148. AUDIO_RX = 21,
  149. JAMLINK0_TX = 22,
  150. JAMLINK0_RX = 23,
  151. JAMLINK1_TX = 24,
  152. JAMLINK1_RX = 25,
  153. JAMLINK2_TX = 26,
  154. JAMLINK2_RX = 27,
  155. JAMLINK3_TX = 28,
  156. JAMLINK3_RX = 29,
  157. ADC0 = 30,
  158. ADC1 = 31,
  159. ADC2 = 32,
  160. PDM_IN = 33,
  161. } device_sel_e;
  162. /**
  163. * @brief Data endianness configuration
  164. */
  165. typedef enum pendian {
  166. PDEFAULT,
  167. PBYTE2,
  168. PBYTE4,
  169. PBYTE8,
  170. } pendian_e;
  171. /**
  172. * @brief Data transfer size configuration
  173. */
  174. typedef enum hsize {
  175. PSBYTE1,
  176. PSBYTE2,
  177. PSBYTE4,
  178. } hsize_e;
  179. /**
  180. * @brief Source address behavior configuration
  181. */
  182. typedef enum src_type {
  183. CONTINUE,
  184. FIXED,
  185. } src_type_e;
  186. /**
  187. * @brief PDMA channel configuration structure
  188. */
  189. typedef struct pdma_ch_cfg {
  190. volatile rt_uint32_t ch_src_type : 1;
  191. volatile rt_uint32_t ch_dev_hsize : 2;
  192. volatile rt_uint32_t reserved0 : 1;
  193. volatile rt_uint32_t ch_dat_endian : 2;
  194. volatile rt_uint32_t reserved1 : 2;
  195. volatile rt_uint32_t ch_dev_blen : 4;
  196. volatile rt_uint32_t ch_priority : 4;
  197. volatile rt_uint32_t ch_dev_tout : 12;
  198. volatile rt_uint32_t reserved2 : 4;
  199. } pdma_ch_cfg_t;
  200. /**
  201. * @brief PDMA channel register structure
  202. */
  203. typedef struct pdma_ch_reg {
  204. volatile rt_uint32_t ch_ctl;
  205. volatile rt_uint32_t ch_status;
  206. volatile pdma_ch_cfg_t ch_cfg;
  207. volatile rt_uint32_t ch_llt_saddr;
  208. volatile rt_uint32_t reserved[4];
  209. } pdma_ch_reg_t;
  210. /**
  211. * @brief PDMA controller register structure
  212. */
  213. typedef struct pdma_reg {
  214. volatile rt_uint32_t pdma_ch_en;
  215. volatile rt_uint32_t dma_int_mask;
  216. volatile rt_uint32_t dma_int_stat;
  217. volatile rt_uint32_t reserved[5];
  218. volatile pdma_ch_reg_t pdma_ch_reg[8];
  219. volatile rt_uint32_t ch_peri_dev_sel[8];
  220. } pdma_reg_t;
  221. /**
  222. * @brief PDMA Linked List Transfer (LLT) node structure
  223. */
  224. typedef struct pdma_llt {
  225. rt_uint32_t line_size : 30; /**< Transfer length in bytes */
  226. rt_uint32_t pause : 1; /**< Pause control flag */
  227. rt_uint32_t node_intr : 1; /**< Node completion interrupt enable */
  228. rt_uint32_t src_addr; /**< Source address */
  229. rt_uint32_t dst_addr; /**< Destination address */
  230. rt_uint32_t next_llt_addr; /**< Next LLT node address */
  231. } pdma_llt_t;
  232. /**
  233. * @brief User PDMA configuration structure
  234. */
  235. typedef struct usr_pdma_cfg {
  236. device_sel_e device; /**< Peripheral device selection */
  237. rt_uint8_t *src_addr; /**< Source address pointer */
  238. rt_uint8_t *dst_addr; /**< Destination address pointer */
  239. rt_uint32_t line_size; /**< Transfer block size */
  240. pdma_ch_cfg_t pdma_ch_cfg; /**< Channel configuration */
  241. } usr_pdma_cfg_t;
  242. /**
  243. * @brief DMA transfer event callback function type
  244. * @param ch DMA channel number where event occurred
  245. * @param is_done Event type indicator:
  246. * - RT_TRUE: Transfer completed successfully
  247. * - RT_FALSE: Transfer terminated due to timeout
  248. * @note This callback will be invoked for both successful completion
  249. * and timeout conditions. The is_done parameter distinguishes
  250. * between these cases.
  251. */
  252. typedef void (*k230_pdma_callback_t)(rt_uint8_t ch, rt_bool_t is_done);
  253. /**
  254. * @brief DMA channel callback structure
  255. * Contains callback function for DMA channel events
  256. */
  257. typedef struct {
  258. k230_pdma_callback_t callback; /* Callback function pointer */
  259. } k230_pdma_chan_cb_t;
  260. /**
  261. * @brief PDMA controller structure
  262. */
  263. typedef struct {
  264. rt_int32_t hardlock; /**< Hardware lock for critical sections */
  265. volatile pdma_reg_t *reg; /**< PDMA register base address */
  266. struct {
  267. rt_uint32_t irq_num; /**< Interrupt number for this channel */
  268. void *llt_va; /**< Virtual address of LLT memory (NULL if not allocated) */
  269. rt_size_t page_size; /**< Page size for each channel */
  270. k230_pdma_chan_cb_t cb; /**< Channel callback functions */
  271. rt_bool_t is_hw_configured; /**< Hardware config flag (must set via k230_pdma_config() before start to avoid BUSY lock) */
  272. rt_bool_t menuconfig_enabled;/**< Channel enabled in menuconfig */
  273. } chan[PDMA_CH_MAX]; /**< Channel configuration array */
  274. } pdma_controller_t;
  275. /**
  276. * @brief Set PDMA callback function for specified channel
  277. */
  278. rt_err_t k230_pdma_set_callback(rt_uint8_t ch, k230_pdma_callback_t func);
  279. /**
  280. * @brief Request an available PDMA channel
  281. */
  282. rt_err_t k230_pdma_request_channel(rt_uint8_t *ch);
  283. /**
  284. * @brief Release allocated PDMA channel
  285. */
  286. rt_err_t k230_pdma_release_channel(rt_uint8_t ch);
  287. /**
  288. * @brief Start PDMA transfer on specified channel
  289. */
  290. rt_err_t k230_pdma_start(rt_uint8_t ch);
  291. /**
  292. * @brief Stop PDMA transfer on specified channel
  293. */
  294. rt_err_t k230_pdma_stop(rt_uint8_t ch);
  295. /**
  296. * @brief Configure PDMA channel parameters
  297. */
  298. rt_err_t k230_pdma_config(rt_uint8_t ch, usr_pdma_cfg_t *ucfg);
  299. #endif /* DRV_PDMA_H_ */