• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2021 HiSilicon (Shanghai) Technologies CO., LIMITED.
3  * Licensed under the Apache License, Version 2.0 (the "License");
4  * you may not use this file except in compliance with the License.
5  * You may obtain a copy of the License at
6  *
7  *     http://www.apache.org/licenses/LICENSE-2.0
8  *
9  * Unless required by applicable law or agreed to in writing, software
10  * distributed under the License is distributed on an "AS IS" BASIS,
11  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12  * See the License for the specific language governing permissions and
13  * limitations under the License.
14  */
15 
16 #include "dmac_hi35xx.h"
17 #include "device_resource_if.h"
18 #include "dmac_core.h"
19 #include "hdf_device_desc.h"
20 #include "hdf_dlist.h"
21 #include "hdf_log.h"
22 #include "los_hw.h"
23 #include "los_hwi.h"
24 #include "los_vm_phys.h"
25 #include "osal_io.h"
26 #include "osal_mem.h"
27 #include "osal_time.h"
28 
29 #define HDF_LOG_TAG dmac_hi35xx
30 
31 #ifdef __cplusplus
32 #if __cplusplus
33 extern "C" {
34 #endif /* __cplusplus */
35 #endif /* __cplusplus */
36 
37 static struct HiDmacPeripheral g_peripheral[HIDMAC_MAX_PERIPHERALS] = {
38     { 0, I2C0_RX_FIFO, HIDMAC_HOST0, 0x40000004, PERI_MODE_8BIT, 0 },
39     { 1, I2C0_TX_FIFO, HIDMAC_HOST0, 0x80000004, PERI_MODE_8BIT, 1 },
40     { 2, I2C1_RX_FIFO, HIDMAC_HOST0, 0x40000004, PERI_MODE_8BIT, 2 },
41     { 3, I2C1_TX_FIFO, HIDMAC_HOST0, 0x80000004, PERI_MODE_8BIT, 3 },
42     { 4, I2C2_RX_FIFO, HIDMAC_HOST0, 0x40000004, PERI_MODE_8BIT, 4 },
43     { 5, I2C2_TX_FIFO, HIDMAC_HOST0, 0x80000004, PERI_MODE_8BIT, 5 },
44     { 6, 0, HIDMAC_NOT_USE, 0, 0, 6 },
45     { 7, 0, HIDMAC_NOT_USE, 0, 0, 7 },
46     { 8, 0, HIDMAC_NOT_USE, 0, 0, 8 },
47     { 9, 0, HIDMAC_NOT_USE, 0, 0, 9 },
48     { 10, 0, HIDMAC_NOT_USE, 0, 0, 10 },
49     { 11, 0, HIDMAC_NOT_USE, 0, 0, 11 },
50     { 12, 0, HIDMAC_NOT_USE, 0, 0, 12 },
51     { 13, 0, HIDMAC_NOT_USE, 0, 0, 13 },
52     { 14, 0, HIDMAC_NOT_USE, 0, 0, 14 },
53     { 15, 0, HIDMAC_NOT_USE, 0, 0, 15 },
54     { 16, UART0_RX_ADDR, HIDMAC_HOST0, 0x47700004, PERI_MODE_8BIT, 16 },
55     { 17, UART0_TX_ADDR, HIDMAC_HOST0, 0x87700004, PERI_MODE_8BIT, 17 },
56     { 18, UART1_RX_ADDR, HIDMAC_HOST0, 0x47700004, PERI_MODE_8BIT, 18 },
57     { 19, UART1_TX_ADDR, HIDMAC_HOST0, 0x87700004, PERI_MODE_8BIT, 19 },
58     { 20, UART2_RX_ADDR, HIDMAC_HOST0, 0x47700004, PERI_MODE_8BIT, 20 },
59     { 21, UART2_TX_ADDR, HIDMAC_HOST0, 0x87700004, PERI_MODE_8BIT, 21 },
60     { 22, 0, HIDMAC_NOT_USE, 0, 0, 22 },
61     { 23, 0, HIDMAC_NOT_USE, 0, 0, 23 },
62     { 24, 0, HIDMAC_NOT_USE, 0, 0, 24 },
63     { 25, 0, HIDMAC_NOT_USE, 0, 0, 25 },
64     { 26, SPI0_RX_FIFO, HIDMAC_HOST0, 0x40000004, PERI_MODE_8BIT, 26 },
65     { 27, SPI0_TX_FIFO, HIDMAC_HOST0, 0x80000004, PERI_MODE_8BIT, 27 },
66     { 28, SPI1_RX_FIFO, HIDMAC_HOST0, 0x40000004, PERI_MODE_16BIT, 28 },
67     { 29, SPI1_TX_FIFO, HIDMAC_HOST0, 0x80000004, PERI_MODE_16BIT, 29 },
68     { 30, SPI2_RX_FIFO, HIDMAC_HOST0, 0x40000004, PERI_MODE_16BIT, 30 },
69     { 31, SPI2_TX_FIFO, HIDMAC_HOST0, 0x80000004, PERI_MODE_16BIT, 31 },
70 };
71 #define HIDMAC_PERIPH_ID_MAX 32
72 
73 #define ERROR_STATUS_NUM_0   0
74 #define ERROR_STATUS_NUM_1   1
75 #define ERROR_STATUS_NUM_2   2
76 #define ERROR_STATUS_MAX     3
77 
HiDmacIsrErrProc(struct DmaCntlr * cntlr,uint16_t chan)78 static int HiDmacIsrErrProc(struct DmaCntlr *cntlr, uint16_t chan)
79 {
80     unsigned int chanErrStats[ERROR_STATUS_MAX];
81 
82     chanErrStats[ERROR_STATUS_NUM_0] = OSAL_READL(cntlr->remapBase + HIDMAC_INT_ERR1_OFFSET);
83     chanErrStats[ERROR_STATUS_NUM_0] = (chanErrStats[ERROR_STATUS_NUM_0] >> chan) & 0x01;
84     chanErrStats[ERROR_STATUS_NUM_1] = OSAL_READL(cntlr->remapBase + HIDMAC_INT_ERR2_OFFSET);
85     chanErrStats[ERROR_STATUS_NUM_1] = (chanErrStats[ERROR_STATUS_NUM_1] >> chan) & 0x01;
86     chanErrStats[ERROR_STATUS_NUM_2] = OSAL_READL(cntlr->remapBase + HIDMAC_INT_ERR3_OFFSET);
87     chanErrStats[ERROR_STATUS_NUM_2] = (chanErrStats[ERROR_STATUS_NUM_2] >> chan) & 0x01;
88     if ((chanErrStats[ERROR_STATUS_NUM_0] | chanErrStats[ERROR_STATUS_NUM_1] |
89         chanErrStats[ERROR_STATUS_NUM_2]) != 0) {
90         HDF_LOGE("%s: Err in hidma %d finish, ERR1:0x%x, ERR2:0x%x, ERR3:0x%x", __func__,
91             chan, chanErrStats[ERROR_STATUS_NUM_0], chanErrStats[ERROR_STATUS_NUM_1],
92             chanErrStats[ERROR_STATUS_NUM_2]);
93         OSAL_WRITEL(1 << chan, cntlr->remapBase + HIDMAC_INT_ERR1_RAW_OFFSET);
94         HDF_LOGE("HIDMAC_INT_ERR1_RAW = 0x%x", OSAL_READL(cntlr->remapBase + HIDMAC_INT_ERR1_RAW_OFFSET));
95         OSAL_WRITEL(1 << chan, cntlr->remapBase + HIDMAC_INT_ERR2_RAW_OFFSET);
96         HDF_LOGE("HIDMAC_INT_ERR2_RAW = 0x%x", OSAL_READL(cntlr->remapBase + HIDMAC_INT_ERR2_RAW_OFFSET));
97         OSAL_WRITEL(1 << chan, cntlr->remapBase + HIDMAC_INT_ERR3_RAW_OFFSET);
98         HDF_LOGE("HIDMAC_INT_ERR3_RAW = 0x%x", OSAL_READL(cntlr->remapBase + HIDMAC_INT_ERR3_RAW_OFFSET));
99         return DMAC_CHN_ERROR;
100     }
101     return 0;
102 }
103 
HiDmacGetChanStat(struct DmaCntlr * cntlr,uint16_t chan)104 static int HiDmacGetChanStat(struct DmaCntlr *cntlr, uint16_t chan)
105 {
106     int ret;
107     unsigned long chanStatus;
108     unsigned long chanTcStatus;
109 
110     chanStatus = OSAL_READL(cntlr->remapBase + HIDMAC_INT_STAT_OFFSET);
111     if ((chanStatus >> chan) & 0x1) {
112         chanTcStatus = OSAL_READL(cntlr->remapBase + HIDMAC_INT_TC1_OFFSET);
113 #ifdef DMAC_HI35XX_DEBUG
114         HDF_LOGD("%s: HIDMAC_INT_TC1 = 0x%lx, chan = %u", __func__, chanTcStatus, chan);
115 #endif
116         chanTcStatus = (chanTcStatus >> chan) & 0x1;
117         if (chanTcStatus != 0) {
118             OSAL_WRITEL(chanTcStatus << chan, cntlr->remapBase + HIDMAC_INT_TC1_RAW_OFFSET);
119             return  DMAC_CHN_SUCCESS;
120         }
121         ret = HiDmacIsrErrProc(cntlr, chan);
122         if (ret != 0) {
123             HDF_LOGE("%s: fail, ret = %d", __func__, ret);
124             return DMAC_CHN_ERROR;
125         }
126         chanTcStatus = OSAL_READL(cntlr->remapBase + HIDMAC_INT_TC2_OFFSET);
127 #ifdef DMAC_HI35XX_DEBUG
128         HDF_LOGD("%s: HIDMAC_INT_TC2 = 0x%lx, chan = %u", __func__, chanTcStatus, chan);
129 #endif
130         chanTcStatus = (chanTcStatus >> chan) & 0x1;
131         if (chanTcStatus != 0) {
132             OSAL_WRITEL(chanTcStatus << chan, cntlr->remapBase + HIDMAC_INT_TC2_RAW_OFFSET);
133         }
134     }
135     return DMAC_NOT_FINISHED;
136 }
137 
HiDmacGetPriId(uintptr_t periphAddr,int transType)138 static unsigned int HiDmacGetPriId(uintptr_t periphAddr, int transType)
139 {
140     unsigned int i;
141 
142     /* only check p2m and m2p */
143     for (i = transType - 1; i < HIDMAC_MAX_PERIPHERALS; i += 2) {
144         if (g_peripheral[i].periphAddr == periphAddr) {
145             return i;
146         }
147     }
148     HDF_LOGE("%s: invalid peripheral addr", __func__);
149     return HIDMAC_PERIPH_ID_MAX;
150 }
151 
HiDmacToLocalWitdh(uint32_t transferWitdh,uint32_t defaultWidth)152 static uint8_t HiDmacToLocalWitdh(uint32_t transferWitdh, uint32_t defaultWidth)
153 {
154     switch (transferWitdh) {
155         case 0x1:
156             return PERI_MODE_8BIT;
157         case 0x2:
158             return PERI_MODE_16BIT;
159         case 0x3:
160             return PERI_MODE_32BIT;
161         case 0x4:
162             return PERI_MODE_64BIT;
163         default:
164             break;
165     }
166     return defaultWidth;
167 }
168 
HiDmacGetChanInfo(struct DmaCntlr * cntlr,struct DmacChanInfo * chanInfo,struct DmacMsg * msg)169 static int32_t HiDmacGetChanInfo(struct DmaCntlr *cntlr, struct DmacChanInfo *chanInfo, struct DmacMsg *msg)
170 {
171     unsigned int periphId;
172     uint8_t localSrcWidth;
173     uint8_t localDstWidth;
174 
175     if (cntlr == NULL) {
176         return HDF_ERR_INVALID_OBJECT;
177     }
178     if (chanInfo == NULL || msg == NULL) {
179         return HDF_ERR_INVALID_PARAM;
180     }
181 
182     if (chanInfo->transType == TRASFER_TYPE_P2M || chanInfo->transType == TRASFER_TYPE_M2P) {
183         periphId = HiDmacGetPriId(DmacMsgGetPeriphAddr(msg), chanInfo->transType);
184         if (periphId >= HIDMAC_PERIPH_ID_MAX) {
185             HDF_LOGE("%s: invalid io address", __func__);
186             return HDF_ERR_INVALID_PARAM;
187         }
188         if (msg->srcWidth != msg->destWidth) {
189             HDF_LOGE("%s: src width:%u != dest width:%u", __func__, msg->srcWidth, msg->destWidth);
190             return HDF_ERR_INVALID_PARAM;
191         }
192         chanInfo->srcWidth = msg->srcWidth;
193         chanInfo->destWidth = chanInfo->srcWidth;
194         localSrcWidth = HiDmacToLocalWitdh(chanInfo->srcWidth, g_peripheral[periphId].transWidth);
195         localDstWidth = localSrcWidth;
196         chanInfo->config = g_peripheral[periphId].transCfg |
197                            (localSrcWidth << HIDMAC_SRC_WIDTH_OFFSET) |
198                            (localDstWidth << HIDMAC_DST_WIDTH_OFFSET) |
199                            (g_peripheral[periphId].dynPeripNum << HIDMAC_PERI_ID_OFFSET);
200     }
201     chanInfo->lliEnFlag = HIDMAC_LLI_ENABLE;
202     return HDF_SUCCESS;
203 }
204 
HiDmacDisable(struct DmaCntlr * cntlr,uint16_t channel)205 static inline void HiDmacDisable(struct DmaCntlr *cntlr, uint16_t channel)
206 {
207     if (cntlr != NULL) {
208         OSAL_WRITEL(HIDMAC_CX_DISABLE, cntlr->remapBase + HIDMAC_CX_CFG_OFFSET(channel));
209     }
210 }
211 
212 
213 #define HIDMAC_32BITS_MASK  0xFFFFFFFF
214 #define HIDMAC_32BITS_SHIFT 32
215 
HiDmacStartM2M(struct DmaCntlr * cntlr,struct DmacChanInfo * chanInfo,uintptr_t psrc,uintptr_t pdst,size_t len)216 static int32_t HiDmacStartM2M(struct DmaCntlr *cntlr, struct DmacChanInfo *chanInfo,
217     uintptr_t psrc, uintptr_t pdst, size_t len)
218 {
219     if (cntlr == NULL) {
220         HDF_LOGE("%s: invalid cntlr", __func__);
221         return HDF_ERR_INVALID_OBJECT;
222     }
223     if (chanInfo == NULL || len == 0) {
224         HDF_LOGE("%s: chanInfo null or invalid len:%zu", __func__, len);
225         return HDF_ERR_INVALID_PARAM;
226     }
227 
228     OSAL_WRITEL(psrc & HIDMAC_32BITS_MASK, cntlr->remapBase + HIDMAC_CX_SRC_OFFSET_L(chanInfo->channel));
229 #ifdef LOSCFG_AARCH64
230     OSAL_WRITEL((psrc >> HIDMAC_32BITS_SHIFT) & HIDMAC_32BITS_MASK,
231         cntlr->remapBase + HIDMAC_CX_SRC_OFFSET_H(chanInfo->channel));
232 #else
233     OSAL_WRITEL(0, cntlr->remapBase + HIDMAC_CX_SRC_OFFSET_H(chanInfo->channel));
234 #endif
235 
236     OSAL_WRITEL(pdst & HIDMAC_32BITS_MASK, cntlr->remapBase + HIDMAC_CX_DST_OFFSET_L(chanInfo->channel));
237 #ifdef LOSCFG_AARCH64
238     OSAL_WRITEL((pdst >> HIDMAC_32BITS_SHIFT) & HIDMAC_32BITS_MASK,
239         cntlr->remapBase + HIDMAC_CX_DST_OFFSET_H(chanInfo->channel));
240 #else
241     OSAL_WRITEL(0, cntlr->remapBase + HIDMAC_CX_DST_OFFSET_H(chanInfo->channel));
242 #endif
243 
244     OSAL_WRITEL(0, cntlr->remapBase + HIDMAC_CX_LLI_OFFSET_L(chanInfo->channel));
245     OSAL_WRITEL(len, cntlr->remapBase + HIDMAC_CX_CNT0_OFFSET(chanInfo->channel));
246     OSAL_WRITEL(HIDMAC_CX_CFG_M2M, cntlr->remapBase + HIDMAC_CX_CFG_OFFSET(chanInfo->channel));
247     return HDF_SUCCESS;
248 }
249 
HiDmacStartLli(struct DmaCntlr * cntlr,struct DmacChanInfo * chanInfo)250 static int32_t HiDmacStartLli(struct DmaCntlr *cntlr, struct DmacChanInfo *chanInfo)
251 {
252     struct DmacLli *plli = NULL;
253 
254     if (cntlr == NULL) {
255         HDF_LOGE("%s: invalid cntlr", __func__);
256         return HDF_ERR_INVALID_OBJECT;
257     }
258     if (chanInfo == NULL || chanInfo->lli == NULL) {
259         HDF_LOGE("%s: chanInfo or lli is null", __func__);
260         return HDF_ERR_INVALID_PARAM;
261     }
262     plli = chanInfo->lli;
263 
264     OSAL_WRITEL(plli->srcAddr & HIDMAC_32BITS_MASK, cntlr->remapBase + HIDMAC_CX_SRC_OFFSET_L(chanInfo->channel));
265 #ifdef LOSCFG_AARCH64
266     OSAL_WRITEL((plli->srcAddr >> HIDMAC_32BITS_SHIFT) & HIDMAC_32BITS_MASK,
267         cntlr->remapBase + HIDMAC_CX_SRC_OFFSET_H(chanInfo->channel));
268 #else
269     OSAL_WRITEL(0, cntlr->remapBase + HIDMAC_CX_SRC_OFFSET_H(chanInfo->channel));
270 #endif
271 
272     OSAL_WRITEL(plli->destAddr & HIDMAC_32BITS_MASK, cntlr->remapBase + HIDMAC_CX_DST_OFFSET_L(chanInfo->channel));
273 #ifdef LOSCFG_AARCH64
274     OSAL_WRITEL((plli->destAddr >> HIDMAC_32BITS_SHIFT) & HIDMAC_32BITS_MASK,
275         cntlr->remapBase + HIDMAC_CX_DST_OFFSET_H(chanInfo->channel));
276 #else
277     OSAL_WRITEL(0, cntlr->remapBase + HIDMAC_CX_DST_OFFSET_H(chanInfo->channel));
278 #endif
279 
280     OSAL_WRITEL(plli->nextLli & HIDMAC_32BITS_MASK, cntlr->remapBase + HIDMAC_CX_LLI_OFFSET_L(chanInfo->channel));
281 #ifdef LOSCFG_AARCH64
282     OSAL_WRITEL((plli->nextLli >> HIDMAC_32BITS_SHIFT) & HIDMAC_32BITS_MASK,
283         cntlr->remapBase + HIDMAC_CX_LLI_OFFSET_H(chanInfo->channel));
284 #else
285     OSAL_WRITEL(0, cntlr->remapBase + HIDMAC_CX_LLI_OFFSET_H(chanInfo->channel));
286 #endif
287 
288     OSAL_WRITEL(plli->count, cntlr->remapBase + HIDMAC_CX_CNT0_OFFSET(chanInfo->channel));
289 
290     OSAL_WRITEL(plli->config | HIDMAC_CX_CFG_CHN_START, cntlr->remapBase + HIDMAC_CX_CFG_OFFSET(chanInfo->channel));
291     return HDF_SUCCESS;
292 }
293 
HiDmacGetCurrDstAddr(struct DmaCntlr * cntlr,uint16_t channel)294 static uintptr_t HiDmacGetCurrDstAddr(struct DmaCntlr *cntlr, uint16_t channel)
295 {
296     if (cntlr == NULL || channel >= HIDMAC_CHANNEL_NUM) {
297         return 0;
298     }
299     return OSAL_READL(cntlr->remapBase + HIDMAC_CX_CUR_DST_OFFSET(channel));
300 }
301 
HiDmacClkEn(uint16_t index)302 static void HiDmacClkEn(uint16_t index)
303 {
304     unsigned long tmp;
305 
306     if (index == 0) {
307         tmp = OSAL_READL(CRG_REG_BASE + HIDMAC_PERI_CRG101_OFFSET);
308         tmp |= 1 << HIDMA0_CLK_OFFSET | 1 << HIDMA0_AXI_OFFSET;
309         OSAL_WRITEL(tmp, CRG_REG_BASE + HIDMAC_PERI_CRG101_OFFSET);
310     }
311 }
312 
HiDmacUnReset(uint16_t index)313 static void HiDmacUnReset(uint16_t index)
314 {
315     unsigned long tmp;
316 
317     if (index == 0) {
318         tmp = OSAL_READL(CRG_REG_BASE + HIDMAC_PERI_CRG101_OFFSET);
319         tmp |= 1 << HIDMA0_RST_OFFSET;
320         OSAL_WRITEL(tmp, CRG_REG_BASE + HIDMAC_PERI_CRG101_OFFSET);
321 
322         tmp = OSAL_READL(CRG_REG_BASE + HIDMAC_PERI_CRG101_OFFSET);
323         tmp &= ~(1 << HIDMA0_RST_OFFSET);
324         OSAL_WRITEL(tmp, CRG_REG_BASE + HIDMAC_PERI_CRG101_OFFSET);
325     }
326 }
327 
Hi35xxDmacInit(struct DmaCntlr * cntlr)328 static int32_t Hi35xxDmacInit(struct DmaCntlr *cntlr)
329 {
330     HDF_LOGI("%s: enter", __func__);
331 
332     HiDmacClkEn(cntlr->index);
333     HiDmacUnReset(cntlr->index);
334 
335     OSAL_WRITEL(HIDMAC_ALL_CHAN_CLR, cntlr->remapBase + HIDMAC_INT_TC1_RAW_OFFSET);
336     OSAL_WRITEL(HIDMAC_ALL_CHAN_CLR, cntlr->remapBase + HIDMAC_INT_TC2_RAW_OFFSET);
337     OSAL_WRITEL(HIDMAC_ALL_CHAN_CLR, cntlr->remapBase + HIDMAC_INT_ERR1_RAW_OFFSET);
338     OSAL_WRITEL(HIDMAC_ALL_CHAN_CLR, cntlr->remapBase + HIDMAC_INT_ERR2_RAW_OFFSET);
339     OSAL_WRITEL(HIDMAC_ALL_CHAN_CLR, cntlr->remapBase + HIDMAC_INT_ERR3_RAW_OFFSET);
340     OSAL_WRITEL(HIDMAC_INT_ENABLE_ALL_CHAN, cntlr->remapBase + HIDMAC_INT_TC1_MASK_OFFSET);
341     OSAL_WRITEL(HIDMAC_INT_ENABLE_ALL_CHAN, cntlr->remapBase + HIDMAC_INT_TC2_MASK_OFFSET);
342     OSAL_WRITEL(HIDMAC_INT_ENABLE_ALL_CHAN, cntlr->remapBase + HIDMAC_INT_ERR1_MASK_OFFSET);
343     OSAL_WRITEL(HIDMAC_INT_ENABLE_ALL_CHAN, cntlr->remapBase + HIDMAC_INT_ERR2_MASK_OFFSET);
344     OSAL_WRITEL(HIDMAC_INT_ENABLE_ALL_CHAN, cntlr->remapBase + HIDMAC_INT_ERR3_MASK_OFFSET);
345     return HDF_SUCCESS;
346 }
347 
HiDmacVaddrToPaddr(void * vaddr)348 static uintptr_t HiDmacVaddrToPaddr(void *vaddr)
349 {
350     return (uintptr_t)LOS_PaddrQuery(vaddr);
351 }
352 
HiDmacPaddrToVaddr(uintptr_t paddr)353 static void *HiDmacPaddrToVaddr(uintptr_t paddr)
354 {
355     return LOS_PaddrToKVaddr((paddr_t)paddr);
356 }
357 
HiDmacCacheInv(uintptr_t vaddr,uintptr_t vend)358 static void HiDmacCacheInv(uintptr_t vaddr, uintptr_t vend)
359 {
360     if (vaddr == 0 || vend == 0) {
361         return;
362     }
363     DCacheInvRange(vaddr, vend);
364 }
365 
HiDmacCacheFlush(uintptr_t vaddr,uintptr_t vend)366 static void HiDmacCacheFlush(uintptr_t vaddr, uintptr_t vend)
367 {
368     if (vaddr == 0 || vend == 0) {
369         return;
370     }
371     DCacheFlushRange(vaddr, vend);
372 }
373 
HiDmacParseHcs(struct DmaCntlr * cntlr,const struct DeviceResourceNode * node)374 static int32_t HiDmacParseHcs(struct DmaCntlr *cntlr, const struct DeviceResourceNode *node)
375 {
376     int32_t ret;
377     struct DeviceResourceIface *drsOps = NULL;
378 
379     if (cntlr == NULL) {
380         return HDF_ERR_INVALID_OBJECT;
381     }
382     drsOps = DeviceResourceGetIfaceInstance(HDF_CONFIG_SOURCE);
383     if (drsOps == NULL || drsOps->GetUint32 == NULL || drsOps->GetUint16 == NULL) {
384         HDF_LOGE("%s: invalid drs ops", __func__);
385         return HDF_ERR_NOT_SUPPORT;
386     }
387 
388     ret = drsOps->GetUint32(node, "reg_pbase", &cntlr->phyBase, 0);
389     if (ret != HDF_SUCCESS) {
390         HDF_LOGE("%s: read reg base fail", __func__);
391         return ret;
392     }
393     cntlr->remapBase = OsalIoRemap((unsigned long)cntlr->phyBase, (unsigned long)cntlr->regSize);
394 
395     ret = drsOps->GetUint32(node, "reg_size", &cntlr->regSize, 0);
396     if (ret != HDF_SUCCESS) {
397         HDF_LOGE("%s: read reg size fail", __func__);
398         return ret;
399     }
400     ret = drsOps->GetUint16(node, "index", &cntlr->index, 0);
401     if (ret != HDF_SUCCESS) {
402         HDF_LOGE("%s: read index fail", __func__);
403         return ret;
404     }
405     ret = drsOps->GetUint32(node, "irq", &cntlr->irq, 0);
406     if (ret != HDF_SUCCESS) {
407         HDF_LOGE("%s: read irq fail", __func__);
408         return ret;
409     }
410     ret = drsOps->GetUint32(node, "max_transfer_size", &cntlr->maxTransSize, 0);
411     if (ret != HDF_SUCCESS) {
412         HDF_LOGE("%s: read max transfer size fail", __func__);
413         return ret;
414     }
415     ret = drsOps->GetUint16(node, "channel_num", &cntlr->channelNum, 0);
416     if (ret != HDF_SUCCESS) {
417         HDF_LOGE("%s: read channel num fail", __func__);
418         return ret;
419     }
420     HDF_LOGI("phybase:0x%x, size:0x%x, index:0x%x, irq:0x%x, max_trans_size:0x%x, chan_num:0x%x",
421         cntlr->phyBase, cntlr->regSize, cntlr->index, cntlr->irq, cntlr->maxTransSize, cntlr->channelNum);
422     return HDF_SUCCESS;
423 }
424 
HiDmacBind(struct HdfDeviceObject * device)425 static int32_t HiDmacBind(struct HdfDeviceObject *device)
426 {
427     struct DmaCntlr *cntlr = NULL;
428 
429     cntlr = DmaCntlrCreate(device);
430     if (cntlr == NULL) {
431         return HDF_ERR_MALLOC_FAIL;
432     }
433     cntlr->getChanInfo = HiDmacGetChanInfo;
434     cntlr->dmacCacheFlush = HiDmacCacheFlush;
435     cntlr->dmacCacheInv = HiDmacCacheInv;
436     cntlr->dmaChanEnable = HiDmacStartLli;
437     cntlr->dmaM2mChanEnable = HiDmacStartM2M;
438     cntlr->dmacChanDisable = HiDmacDisable;
439     cntlr->dmacVaddrToPaddr = HiDmacVaddrToPaddr;
440     cntlr->dmacPaddrToVaddr = HiDmacPaddrToVaddr;
441     cntlr->dmacGetChanStatus = HiDmacGetChanStat;
442     cntlr->dmacGetCurrDestAddr = HiDmacGetCurrDstAddr;
443     device->service = &cntlr->service;
444     return HDF_SUCCESS;
445 }
446 
HiDmacInit(struct HdfDeviceObject * device)447 static int32_t HiDmacInit(struct HdfDeviceObject *device)
448 {
449     int32_t ret;
450     struct DmaCntlr *cntlr = NULL;
451 
452     if (device == NULL || device->property == NULL) {
453         HDF_LOGE("%s: device or property null", __func__);
454         return HDF_ERR_INVALID_OBJECT;
455     }
456 
457     cntlr = CONTAINER_OF(device->service, struct DmaCntlr, service);
458     ret = HiDmacParseHcs(cntlr, device->property);
459     if (ret != HDF_SUCCESS) {
460         return ret;
461     }
462     ret = Hi35xxDmacInit(cntlr);
463     if (ret != HDF_SUCCESS) {
464         return ret;
465     }
466     return DmacCntlrAdd(cntlr);
467 }
468 
HiDmacRelease(struct HdfDeviceObject * device)469 static void HiDmacRelease(struct HdfDeviceObject *device)
470 {
471     struct DmaCntlr *cntlr = NULL;
472 
473     if (device == NULL) {
474         return;
475     }
476     cntlr = CONTAINER_OF(device->service, struct DmaCntlr, service);
477     DmacCntlrRemove(cntlr);
478     DmaCntlrDestroy(cntlr);
479 }
480 
481 struct HdfDriverEntry g_hiDmacEntry = {
482     .moduleVersion = 1,
483     .Bind = HiDmacBind,
484     .Init = HiDmacInit,
485     .Release = HiDmacRelease,
486     .moduleName = "HDF_PLATFORM_DMAC",
487 };
488 HDF_INIT(g_hiDmacEntry);
489 #ifdef __cplusplus
490 #if __cplusplus
491 }
492 #endif /* __cplusplus */
493 #endif /* __cplusplus */
494