• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2020-2021 Huawei Device Co., Ltd.
3  *
4  * HDF is dual licensed: you can use it either under the terms of
5  * the GPL, or the BSD license, at your option.
6  * See the LICENSE file in the root of this repository for complete details.
7  */
8 
9 #ifndef DMAC_CORE_H
10 #define DMAC_CORE_H
11 
12 #include "hdf_base.h"
13 #include "hdf_device.h"
14 #include "hdf_device_desc.h"
15 #include "hdf_object.h"
16 #include "los_event.h"
17 #include "osal_mutex.h"
18 #include "osal_spinlock.h"
19 
20 #ifdef __cplusplus
21 #if __cplusplus
22 extern "C" {
23 #endif
24 #endif /* __cplusplus */
25 
26 #define PERIPH_ADDR_INVALID               0xfff
27 #define DMAC_CHAN_NUM_MAX                 100
28 
29 #define DmaEventInit(event)               LOS_EventInit(event)
30 #define DmaEventSignal(event, bit)        LOS_EventWrite(event, bit)
31 #define DmaEventWait(event, bit, timeout) LOS_EventRead(event, bit, LOS_WAITMODE_OR + LOS_WAITMODE_CLR, timeout)
32 
33 typedef void DmacCallback(void *callbackData, int status);
34 typedef EVENT_CB_S DmacEvent;
35 
36 /* definition for the return value */
37 enum DmacErrorNumber {
38     DMAC_ERROR_BASE                       = 0x100,
39     DMAC_CHANNEL_INVALID                  = DMAC_ERROR_BASE + 1,
40     DMAC_TRXFERSIZE_INVALID               = DMAC_ERROR_BASE + 2,
41     DMAC_SOURCE_ADDRESS_INVALID           = DMAC_ERROR_BASE + 3,
42     DMAC_DESTINATION_ADDRESS_INVALID      = DMAC_ERROR_BASE + 4,
43     DMAC_MEMORY_ADDRESS_INVALID           = DMAC_ERROR_BASE + 5,
44     DMAC_PERIPHERAL_ID_INVALID            = DMAC_ERROR_BASE + 6,
45     DMAC_DIRECTION_ERROR                  = DMAC_ERROR_BASE + 7,
46     DMAC_TRXFER_ERROR                     = DMAC_ERROR_BASE + 8,
47     DMAC_LLIHEAD_ERROR                    = DMAC_ERROR_BASE + 9,
48     DMAC_SWIDTH_ERROR                     = DMAC_ERROR_BASE + 0xa,
49     DMAC_LLI_ADDRESS_INVALID              = DMAC_ERROR_BASE + 0xb,
50     DMAC_TRANS_CONTROL_INVALID            = DMAC_ERROR_BASE + 0xc,
51     DMAC_MEMORY_ALLOCATE_ERROR            = DMAC_ERROR_BASE + 0xd,
52     DMAC_NOT_FINISHED                     = DMAC_ERROR_BASE + 0xe,
53     DMAC_TIMEOUT                          = DMAC_ERROR_BASE + 0xf,
54     DMAC_CHN_SUCCESS                      = DMAC_ERROR_BASE + 0x10,
55     DMAC_CHN_ERROR                        = DMAC_ERROR_BASE + 0x11,
56     DMAC_CHN_TIMEOUT                      = DMAC_ERROR_BASE + 0x12,
57     DMAC_CHN_ALLOCAT                      = DMAC_ERROR_BASE + 0x13,
58     DMAC_CHN_VACANCY                      = DMAC_ERROR_BASE + 0x14,
59 };
60 
61 enum DmacEvent {
62     DMAC_EVENT_DONE                       = 0x1,
63     DMAC_EVENT_ERROR                      = 0x2,
64 };
65 #define DMA_EVENT_WAIT_DEF_TIME           ((LOSCFG_BASE_CORE_TICK_PER_SECOND) * 5)
66 
67 enum DmacTransferType {
68     TRASFER_TYPE_M2M = 0x0,
69     TRASFER_TYPE_P2M = 0x1,
70     TRASFER_TYPE_M2P = 0x2,
71 };
72 
73 struct DmacMsg {
74     uintptr_t srcAddr;
75     uintptr_t destAddr;
76     uint8_t srcWidth;         // src data width in bytes
77     uint8_t destWidth;        // dest data width in bytes
78     uint8_t transType;        // 0: mem to mem; 1: periph to mem; 2:mem to periph
79     size_t transLen;
80     DmacCallback *cb;
81     void *para;
82 };
83 
DmacMsgGetPeriphAddr(struct DmacMsg * msg)84 static inline uintptr_t DmacMsgGetPeriphAddr(struct DmacMsg *msg)
85 {
86     return (msg->transType == TRASFER_TYPE_M2P) ? msg->destAddr :
87         (msg->transType == TRASFER_TYPE_P2M) ? msg->srcAddr : PERIPH_ADDR_INVALID;
88 }
89 
90 #define DMAC_LLI_HEAD         \
91     uintptr_t nextLli;        \
92     uintptr_t reserved0[6];   \
93     unsigned long count;      \
94     uintptr_t srcAddr;        \
95     uintptr_t reserved1;      \
96     uintptr_t destAddr;       \
97     uintptr_t reserved2;      \
98     unsigned long config
99 
100 struct DmacLliHead {
101     DMAC_LLI_HEAD;
102 };
103 #define DMAC_LLI_HEAD_SIZE    (sizeof(struct DmacLliHead))
104 
105 #define DMAC_LLI_SIZE         64 // must be 64 Bytes aligned
106 struct DmacLli {
107     DMAC_LLI_HEAD;
108     uint8_t pad[DMAC_LLI_SIZE - DMAC_LLI_HEAD_SIZE];
109 };
110 
111 struct DmacChanInfo {
112     uint16_t channel;
113     int status;
114     int useStatus;
115     int transType;
116     uint8_t srcWidth;         // src data width in bytes
117     uint8_t destWidth;        // dest data width in bytes
118     unsigned long config;     // cpu width expected
119     uintptr_t lliEnFlag;
120     DmacEvent waitEvent;
121     DmacCallback *callback;
122     void *callbackData;
123     uint16_t lliCnt;
124     struct DmacLli *lli;
125     void *dummyPage;
126 };
127 
128 struct DmaCntlr {
129     struct IDeviceIoService service;
130     struct HdfDeviceObject *device;
131     uint16_t index;
132     uint32_t irq;
133     uintptr_t phyBase;
134     volatile unsigned char *remapBase;
135     size_t regSize;
136     size_t maxTransSize;
137     uint16_t channelNum;
138     OsalSpinlock lock;
139     struct DmacChanInfo *channelList;
140     int32_t (*getChanInfo)(struct DmaCntlr *cntlr, struct DmacChanInfo *chanInfo, struct DmacMsg *msg);
141     int32_t (*dmaChanEnable)(struct DmaCntlr *cntlr, struct DmacChanInfo *chanInfo);
142     int32_t (*dmaM2mChanEnable)(struct DmaCntlr *cntlr, struct DmacChanInfo *chanInfo,
143         uintptr_t src, uintptr_t dest, size_t length);
144     void (*dmacChanDisable)(struct DmaCntlr *cntlr, uint16_t channel);
145     void (*dmacCacheInv)(uintptr_t vaddr, uintptr_t vend);
146     void (*dmacCacheFlush)(uintptr_t vaddr, uintptr_t vend);
147     void *(*dmacPaddrToVaddr)(uintptr_t paddr);
148     uintptr_t (*dmacVaddrToPaddr)(void *vaddr);
149     int (*dmacGetChanStatus)(struct DmaCntlr *cntlr, uint16_t chan);
150     uintptr_t (*dmacGetCurrDestAddr)(struct DmaCntlr *cntlr, uint16_t chan);
151     void *private;
152 };
153 
154 #ifdef LOSCFG_DRIVERS_HDF_PLATFORM_DMAC
155 struct DmaCntlr *DmaCntlrCreate(struct HdfDeviceObject *dev);
156 
157 void DmaCntlrDestroy(struct DmaCntlr *cntlr);
158 
159 int32_t DmacCntlrAdd(struct DmaCntlr *cntlr);
160 
161 void DmacCntlrRemove(struct DmaCntlr *cntlr);
162 
163 int32_t DmaCntlrTransfer(struct DmaCntlr *cntlr, struct DmacMsg *msg);
164 
165 uintptr_t DmaGetCurrChanDestAddr(struct DmaCntlr *cntlr, uint16_t chan);
166 #else
DmaCntlrCreate(struct HdfDeviceObject * dev)167 static inline struct DmaCntlr *DmaCntlrCreate(struct HdfDeviceObject *dev)
168 {
169     (void)dev;
170     return NULL;
171 }
172 
DmaCntlrDestroy(struct DmaCntlr * cntlr)173 static inline void DmaCntlrDestroy(struct DmaCntlr *cntlr)
174 {
175     (void)cntlr;
176     return;
177 }
178 
DmacCntlrAdd(struct DmaCntlr * cntlr)179 static inline int32_t DmacCntlrAdd(struct DmaCntlr *cntlr)
180 {
181     (void)cntlr;
182     return HDF_ERR_NOT_SUPPORT;
183 }
184 
DmacCntlrRemove(struct DmaCntlr * cntlr)185 static inline void DmacCntlrRemove(struct DmaCntlr *cntlr)
186 {
187     (void)cntlr;
188     return;
189 }
190 
DmaCntlrTransfer(struct DmaCntlr * cntlr,struct DmacMsg * msg)191 static inline int32_t DmaCntlrTransfer(struct DmaCntlr *cntlr, struct DmacMsg *msg)
192 {
193     (void)cntlr;
194     (void)msg;
195     return HDF_ERR_NOT_SUPPORT;
196 }
197 
DmaGetCurrChanDestAddr(struct DmaCntlr * cntlr,uint16_t chan)198 static inline uintptr_t DmaGetCurrChanDestAddr(struct DmaCntlr *cntlr, uint16_t chan)
199 {
200     (void)cntlr;
201     (void)chan;
202     return 0;
203 }
204 #endif
205 
206 #ifdef __cplusplus
207 #if __cplusplus
208 }
209 #endif
210 #endif /* __cplusplus */
211 
212 #endif /* DMAC_CORE_H */
213