summaryrefslogtreecommitdiff
path: root/bsp/xuantie/libraries/xuantie_libraries/csi/csi2/include/drv/dma.h
blob: a97b7f80fd70fef9976695678beab930e605cf6c (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
 /*
 * Copyright (C) 2017-2024 Alibaba Group Holding Limited
 *
 * SPDX-License-Identifier: Apache-2.0
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

/******************************************************************************
 * @file     dma.h
 * @brief    header file for dma driver
 * @version  V1.0
 * @date     08. Apr 2020
 * @model    dma
 ******************************************************************************/

#ifndef _DRV_DMA_H_
#define _DRV_DMA_H_

#include <stdint.h>
#include <stdio.h>
#include <drv/common.h>
#include <drv/list.h>

#ifdef __cplusplus
extern "C" {
#endif

/****** DMA Event *****/
typedef enum {
    DMA_EVENT_TRANSFER_DONE       = 0,  ///< transfer complete
    DMA_EVENT_TRANSFER_HALF_DONE,       ///< transfer half done
    DMA_EVENT_TRANSFER_ERROR,           ///< transfer error
} csi_dma_event_t;

typedef enum {
    DMA_ADDR_INC    = 0,
    DMA_ADDR_DEC,
    DMA_ADDR_CONSTANT
} csi_dma_addr_inc_t;

typedef enum {
    DMA_DATA_WIDTH_8_BITS  = 0,
    DMA_DATA_WIDTH_16_BITS,
    DMA_DATA_WIDTH_32_BITS,
    DMA_DATA_WIDTH_64_BITS,
    DMA_DATA_WIDTH_128_BITS,
    DMA_DATA_WIDTH_512_BITS
} csi_dma_data_width_t;

typedef enum {
    DMA_MEM2MEM     = 0,
    DMA_MEM2PERH,
    DMA_PERH2MEM,
} csi_dma_trans_dir_t;

typedef struct {
    uint8_t ctrl_idx;
    uint8_t ch_idx;
} csi_dma_ch_desc_t;

typedef struct {
    uint16_t dev_tag;
    uint8_t  ctrl_idx;
    const csi_dma_ch_desc_t *ch_list;
} csi_dma_ch_spt_list_t;

typedef struct {
    csi_dma_addr_inc_t          src_inc;        ///< source address increment
    csi_dma_addr_inc_t          dst_inc;        ///< destination address increment
    csi_dma_data_width_t        src_tw;         ///< source transfer width in byte
    csi_dma_data_width_t        dst_tw;         ///< destination transfer width in byte
    csi_dma_trans_dir_t         trans_dir;      ///< transfer direction
    uint16_t                    handshake;      ///< handshake id
    uint16_t                    group_len;      ///< group transaction length (unit: bytes)
    uint8_t                     src_reload_en;  ///< 1:dma enable src addr auto reload, 0:disable
    uint8_t                     dst_reload_en;  ///< 1:dma enable dst addr auto reload, 0:disable
    uint8_t                     half_int_en;    ///< 1:dma enable half interrupt, 0: disable
    uint8_t                     lli_src_en;     ///< 1:dma enable llp, 0 disable
    uint8_t                     lli_dst_en;     ///< 1:dma enable llp, 0 disable
} csi_dma_ch_config_t;

#ifndef DMA_LLI_SIZE
#define DMA_LLI_SIZE 28
#endif

#define DEFINE_DESC_BUF(buf_name, num) uint8_t buf_name[num * DMA_LLI_SIZE]

typedef struct csi_dma_ch csi_dma_ch_t;

struct csi_dma_ch {
    void                *parent;
    int8_t              ctrl_id;
    int8_t              ch_id;
    void                (*callback)(csi_dma_ch_t *dma_ch, csi_dma_event_t event, void *arg);
    void                *arg;
    uint32_t            lli_num;                    //lli buffer len
    uint32_t            lli_count;                  //lli data count
    int32_t             lli_w_p;                    //write position
    int32_t             lli_r_p;                    //read position
    void                *lli;                       //lli buffer
    uint32_t            lli_loop_buf0;              //lli loop data
    uint32_t            lli_loop_buf1;              //lli loop data
    uint8_t             lli_loop[DMA_LLI_SIZE];     //lli loop handle
    int16_t             etb_ch_id;
    slist_t             next;
};

typedef struct {
    csi_dev_t           dev;
    slist_t             head;
    uint32_t            alloc_status;
    uint32_t            ch_num;
    void                *priv;
} csi_dma_t;

/**
  \brief       Init dma controller
  \param[in]   dma     the dma controller operate handle
  \param[in]   ctrl_id  the dma controller id
  \return      csi error code
*/
csi_error_t csi_dma_init(csi_dma_t *dma, int8_t ctrl_id);

/**
  \brief       Uninit dma controller
  \param[in]   dma     the dma controller operate handle
  \return      none
*/
void csi_dma_uninit(csi_dma_t *dma);

/**
  \brief       Alloc a dma channel
  \param[in]   dma_ch   the dma channel operate handle
  \param[in]   ch_id    the channel id  of dma; when set -1, means auto alloc
  \param[in]   ctrl_id  the dma controller id; when set -1, means auto alloc
  \return      csi error code
*/
csi_error_t csi_dma_ch_alloc(csi_dma_ch_t *dma_ch, int8_t ch_id, int8_t ctrl_id);

/**
  \brief       Free a dma channel
  \param[in]   dma_ch   the dma channel operate handle
  \return      none
*/
void csi_dma_ch_free(csi_dma_ch_t *dma_ch);

/**
  \brief       Config a dma channel
  \param[in]   dma_ch   the dma channel operate handle
  \param[in]   config   the config structure for dma channel
  \return      csi error code
*/
csi_error_t csi_dma_ch_config(csi_dma_ch_t *dma_ch, csi_dma_ch_config_t *config);

/**
  \brief       Start a dma channel
  \param[in]   dma_ch       the dma channel operate handle
  \param[in]   psrcaddr     transfer source address
  \param[in]   pdstaddr     transfer destination address
  \param[in]   length       transfer length (unit: bytes), if set data_width is 16, the length should be the multiple of 2, and
                            if set data_width is 32, the length should be the multiple of 4
  \return      none
*/
void csi_dma_ch_start(csi_dma_ch_t *dma_ch, void *srcaddr, void *dstaddr, uint32_t length);

/**
  \brief       Stop a dma channel
  \param[in]   dma_ch       the dma channel operate handle
  \return      none
*/
void csi_dma_ch_stop(csi_dma_ch_t *dma_ch);

/**
  \brief       Attach the callback handler to DMA channel
  \param[in]   dma_ch     operate handle.
  \param[in]   callback   callback function
  \param[in]   arg        user can define it by himself as callback's param
  \return      error code
*/
csi_error_t csi_dma_ch_attach_callback(csi_dma_ch_t *dma_ch, void *callback, void *arg);

/**
  \brief       detach the callback handler
  \param[in]   uart  operate handle.
*/
void        csi_dma_ch_detach_callback(csi_dma_ch_t *dma_ch);

/**
  \brief       enable dma power manage
  \param[in]   dma  dma handle to operate.
  \return      error code
*/
csi_error_t csi_dma_enable_pm(csi_dma_t *dma);

/**
  \brief       disable dma power manage
  \param[in]   dma  dma handle to operate.
*/
void        csi_dma_disable_pm(csi_dma_t *dma);

#ifdef __cplusplus
}
#endif

#endif /* _CSI_DMA_H_ */