1 /*
2  * Copyright (C) 2017-2019 Alibaba Group Holding Limited
3  */
4 
5 /******************************************************************************
6  * @file     drv_dmac.h
7  * @brief    header file for dmac driver
8  * @version  V1.0
9  * @date     02. June 2017
10  * @model    dmac
11  ******************************************************************************/
12 #ifndef _CSI_DMA_H_
13 #define _CSI_DMA_H_
14 
15 #include <stdint.h>
16 #include <drv_common.h>
17 
18 #ifdef __cplusplus
19 extern "C" {
20 #endif
21 /**
22 \brief DMA Driver Capabilities.
23 */
24 typedef struct {
25     uint32_t unalign_addr : 1;          ///< support for unalign address transfer when memory is source
26 } dma_capabilities_t;
27 
28 typedef enum {
29     DMA_STATE_FREE = 0,       ///< DMA channel not yet initialized or disabled
30     DMA_STATE_READY,          ///< DMA channel process success and ready for use, but not start yet
31     DMA_STATE_BUSY,           ///< DMA channel process is ongoing
32     DMA_STATE_DONE,           ///< DMA channel transfer done
33     DMA_STATE_ERROR,          ///< DMA channel transfer error
34 } dma_status_e;
35 
36 /****** DMA specific error codes *****/
37 typedef enum {
38     EDRV_DMA_MODE  = (DRV_ERROR_SPECIFIC + 1),     ///< Specified Mode not supported
39 } dma_error_e;
40 
41 /****** DMA Event *****/
42 typedef enum {
43     DMA_EVENT_TRANSFER_DONE        = 0,  ///< transfer complete
44     DMA_EVENT_TRANSFER_HALF_DONE   = 1,  ///< transfer half done
45     DMA_EVENT_TRANSFER_MODE_DONE   = 2,  ///< transfer complete in a certain dma trigger mode.
46     DMA_EVENT_CAHNNEL_PEND         = 3,  ///< it happens when there is a low priority channel was preempted by a high priority channel
47     DMA_EVENT_TRANSFER_ERROR       = 4,  ///< transfer error
48 } dma_event_e;
49 
50 typedef enum {
51     DMA_ADDR_INC    = 0,
52     DMA_ADDR_DEC,
53     DMA_ADDR_CONSTANT
54 } dma_addr_inc_e;
55 
56 typedef enum {
57     DMA_MEM2MEM     = 0,
58     DMA_MEM2PERH,
59     DMA_PERH2MEM,
60     DMA_PERH2PERH,
61 } dma_trans_type_e;
62 
63 typedef enum {
64     DMA_SINGLE_TRIGGER     = 0,
65     DMA_GROUP_TRIGGER,
66     DMA_BLOCK_TRIGGER
67 } dma_trig_trans_mode_e;
68 
69 typedef enum {
70     DMA_DIR_DEST = 0,
71     DMA_DIR_SOURCE
72 } dma_single_dir_e;
73 
74 typedef enum {
75     DMA_ADDR_LITTLE = 0,
76     DMA_ADDR_BIG
77 } dma_addr_endian_e;
78 
79 typedef enum {
80     DMA_MODE_HARDWARE = 0,
81     DMA_MODE_SOFTWARE
82 } dma_channel_req_mode_e;
83 
84 typedef struct {
85     dma_addr_inc_e         src_inc;        ///< source address increment
86     dma_addr_inc_e         dst_inc;        ///< destination address increment
87     dma_addr_endian_e      src_endian;     ///< source read data little-big endian change control.
88     dma_addr_endian_e      dst_endian;     ///< destination write data little-big endian change control.
89     uint8_t                src_tw;         ///< source transfer width in byte
90     uint8_t                dst_tw;         ///< destination transfer width in byte
91     uint8_t                hs_if;          ///< a hardware handshaking interface (optional).
92     uint8_t                preemption;     ///< determine whether if a channel can be preempted by a higher priority channel, 0 -- not allow preempt, 1 -- allow preempt.
93     dma_trans_type_e       type;           ///< transfer type
94     dma_trig_trans_mode_e  mode;           ///< channel trigger mode
95     dma_channel_req_mode_e ch_mode;        ///< software or hardware to tigger dma channel work.
96     dma_single_dir_e       single_dir;     ///< after select single mode control for source(read) or destination(write) transfer.
97     uint32_t               group_len;      ///< group transaction length (unit: bytes) when use DMA_GROUP_TRIGGER mode.
98     uint32_t               src_reload_en;  ///< 1:dma enable src addr auto reload, 0:disable
99     uint32_t               dest_reload_en; ///< 1:dma enable dst addr auto reload, 0:disable
100 } dma_config_t;
101 
102 typedef void (*dma_event_cb_t)(int32_t ch, dma_event_e event, void *arg);   ///< Pointer to \ref dma_event_cb_t : dmac event call back.
103 
104 /**
105   \brief     get one free dma channel
106   \param[in] ch channel num. if -1 then allocate a free channal in this dma
107                              else allocate a fix channal
108   \return    dma channel num. if -1 alloc channle error
109  */
110 int32_t csi_dma_alloc_channel_ex(int32_t ch);
111 
112 /**
113   \brief     get one free dma channel
114   \return    dma channel num. if -1 alloc channle error
115  */
116 int32_t csi_dma_alloc_channel(void);
117 
118 /**
119   \brief       control dma power.
120   \param[in]   ch      dma channel num
121   \param[in]   state   power state.\ref csi_power_stat_e.
122   \return      error code
123 */
124 int32_t csi_dma_power_control(int32_t ch, csi_power_stat_e state);
125 
126 /**
127   \brief       Get driver capabilities.
128   \param[in]   ch      dma channel num
129   \return      \ref dma_capabilities_t
130 */
131 dma_capabilities_t csi_dma_get_capabilities(int32_t ch);
132 
133 /**
134   \brief        release dma channel and related resources
135   \param[in]    ch dma channel num
136   \return       error code
137  */
138 void csi_dma_release_channel(int32_t ch);
139 
140 /**
141   \brief        config dma channel
142   \param[in]    ch          dma channel num
143   \param[in]    config      dma channel transfer configure
144   \param[in]    cb_event    Pointer to \ref dma_event_cb_t
145   \return       error code
146  */
147 int32_t csi_dma_config_channel(int32_t ch, dma_config_t *config, dma_event_cb_t cb_event, void *cb_arg);
148 
149 /**
150   \brief       start generate dma channel signal.
151   \param[in]   ch          dma channel num
152   \param[in]   psrcaddr    dma transfer source address
153   \param[in]   pdstaddr    dma transfer destination address
154   \param[in]   length      dma transfer length (unit: bytes).
155 */
156 void csi_dma_start(int32_t ch, void *psrcaddr, void *pdstaddr, uint32_t length);
157 
158 /**
159   \brief       Stop generate dma channel signal.
160   \param[in]   ch     dma channel num
161 */
162 void csi_dma_stop(int32_t ch);
163 
164 /**
165   \brief       start generate dma channel cyclic transfer.
166   \param[in]   ch          dma channel num
167   \param[in]   psrcaddr    dma transfer source address
168   \param[in]   pdstaddr    dma transfer destination address
169   \param[in]   cycle_len   The length of a cycle
170   \param[in]   cycle_num   the number of a cycle
171   \return       error code
172 */
173 int32_t csi_dma_cyclic_prep(int32_t ch, void *psrcaddr, void *pdstaddr, uint32_t cycle_len, uint32_t cycle_num);
174 /**
175   \brief       start generate dma channel cyclic transfer.
176   \param[in]   ch   dma channel num
177 */
178 
179 void csi_dma_cyclic_start(int32_t ch);
180 
181 /**
182   \brief       Stop generate dma channel cyclic transfer.
183   \param[in]   ch   dma channel num
184 */
185 void csi_dma_cyclic_stop(int32_t ch);
186 
187 /**
188   \brief       Get DMA channel status.
189   \param[in]   ch  dma channel num
190   \return      DMA status \ref dma_status_e
191 */
192 dma_status_e csi_dma_get_status(int32_t ch);
193 
194 #ifdef __cplusplus
195 }
196 #endif
197 
198 #endif /* _CSI_DMA_H_ */
199 
200