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