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