1 /*
2  * Copyright (C) 2022 HiHope Open Source Organization .
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 #include <sound/memalloc.h>
9 #include <linux/delay.h>
10 #include <linux/device.h>
11 #include <linux/dma-mapping.h>
12 #include <linux/init.h>
13 #include <linux/kernel.h>
14 #include <linux/module.h>
15 #include <linux/moduleparam.h>
16 #include <linux/notifier.h>
17 #include <linux/of.h>
18 #include <linux/of_dma.h>
19 #include <linux/of_device.h>
20 #include <linux/platform_device.h>
21 #include <linux/slab.h>
22 #include <linux/stat.h>
23 #include <linux/string.h>
24 #include <linux/sysfs.h>
25 #include <linux/suspend.h>
26 
27 #include "audio_platform_base.h"
28 #include "osal_io.h"
29 #include "osal_uaccess.h"
30 #include "audio_driver_log.h"
31 #include "rk3588_dma_ops.h"
32 #include "rk3588_dai_linux.h"
33 
34 #define HDF_LOG_TAG rk3588_platform_ops
35 
36 #define I2S0_ADDR 0xfe470000
37 
38 
39 #define DMA_RX_CHANNEL 0
40 #define DMA_TX_CHANNEL 1
41 #define DMA_CHANNEL_MAX 2
42 
43 struct HdfDeviceObject *g_device;
44 
45 struct DmaRuntimeData {
46     struct dma_chan *dmaChn[DMA_CHANNEL_MAX];
47     dma_cookie_t cookie[DMA_CHANNEL_MAX];
48     uint32_t streamType;
49 };
50 
51 static struct dma_chan *g_dmaChn[DMA_CHANNEL_MAX];
52 static dma_cookie_t g_cookie[DMA_CHANNEL_MAX];
53 static struct device *g_dmaDev;
54 static const char *g_i2s1DtsTreePath = "/i2s@fe470000";
55 
getDmaDevice(void)56 struct device *getDmaDevice(void)
57 {
58     struct device_node    *dmaOfNode;
59     struct platform_device *platformdev;
60 
61     dmaOfNode = of_find_node_by_path(g_i2s1DtsTreePath);
62     if (dmaOfNode == NULL) {
63         AUDIO_DEVICE_LOG_ERR("get device node failed.");
64         return NULL;
65     }
66     platformdev = of_find_device_by_node(dmaOfNode);
67     if (platformdev == NULL) {
68         AUDIO_DEVICE_LOG_ERR("get platformdev failed.");
69         return NULL;
70     }
71     g_dmaDev = &platformdev->dev;
72     return g_dmaDev;
73 }
74 
AudioDmaDeviceInit(const struct AudioCard *card, const struct PlatformDevice *platform)75 int32_t AudioDmaDeviceInit(const struct AudioCard *card, const struct PlatformDevice *platform)
76 {
77     struct PlatformData *data = NULL;
78     static const char * const dmaChannelNames[] = {
79         [DMA_RX_CHANNEL] = "rx",
80         [DMA_TX_CHANNEL] = "tx",
81     };
82     uint32_t i = 0;
83     struct device *dmaDevice = getDmaDevice();
84 
85     if (card == NULL) {
86         AUDIO_DEVICE_LOG_ERR("card is null.");
87         return HDF_FAILURE;
88     }
89     g_device = card->device;
90 
91     data = PlatformDataFromCard(card);
92     if (data == NULL) {
93         AUDIO_DEVICE_LOG_ERR("PlatformDataFromCard failed.");
94         return HDF_FAILURE;
95     }
96     if (data->platformInitFlag == true) {
97         AUDIO_DRIVER_LOG_DEBUG("platform init complete!");
98         return HDF_SUCCESS;
99     }
100     data->platformInitFlag = true;
101     for (i = 0; i <= 1; i++) {
102         g_dmaChn[i] = dma_request_slave_channel(dmaDevice,
103             dmaChannelNames[i]);
104         if (g_dmaChn[i] == NULL) {
105             AUDIO_DEVICE_LOG_ERR("dma_request_slave_channel streamType=%d failed", i);
106             return HDF_FAILURE;
107         }
108     }
109     AUDIO_DEVICE_LOG_DEBUG("success.");
110     return HDF_SUCCESS;
111 }
112 
113 
DmaRtdMemAlloc(struct PlatformData *data, enum AudioStreamType streamType)114 static int32_t DmaRtdMemAlloc(struct PlatformData *data, enum AudioStreamType streamType)
115 {
116     struct DmaRuntimeData *dmaRtd = NULL;
117 
118     if (data == NULL) {
119         AUDIO_DEVICE_LOG_ERR("data is null.");
120         return HDF_FAILURE;
121     }
122 
123     dmaRtd = kzalloc(sizeof(*dmaRtd), GFP_KERNEL);
124     if (!dmaRtd) {
125         AUDIO_DEVICE_LOG_ERR("AudioRenderBuffInit: fail.");
126         return HDF_FAILURE;
127     }
128     data->dmaPrv = dmaRtd;
129     dmaRtd->streamType = streamType;
130     AUDIO_DEVICE_LOG_DEBUG("streamType = %d", streamType);
131     dmaRtd->dmaChn[streamType] = g_dmaChn[streamType];
132     AUDIO_DEVICE_LOG_DEBUG("success.");
133     return HDF_SUCCESS;
134 }
135 
Rk3588DmaBufAlloc(struct PlatformData *data, const enum AudioStreamType streamType)136 int32_t Rk3588DmaBufAlloc(struct PlatformData *data, const enum AudioStreamType streamType)
137 {
138     uint32_t preallocBufSize;
139     struct device *dmaDevice = getDmaDevice();
140 
141     if (data == NULL) {
142         AUDIO_DEVICE_LOG_ERR("data is null");
143         return HDF_FAILURE;
144     }
145 
146     if (dmaDevice == NULL) {
147         AUDIO_DEVICE_LOG_ERR("dmaDevice is null");
148         return HDF_FAILURE;
149     }
150 
151     if (streamType == AUDIO_CAPTURE_STREAM) {
152         if (data->captureBufInfo.virtAddr == NULL) {
153             preallocBufSize = data->captureBufInfo.cirBufMax;
154             dmaDevice->coherent_dma_mask = 0xffffffffUL;
155             AUDIO_DEVICE_LOG_DEBUG("AUDIO_CAPTURE_STREAM");
156             data->captureBufInfo.virtAddr = dma_alloc_wc(dmaDevice, preallocBufSize,
157                 (dma_addr_t *)&data->captureBufInfo.phyAddr, GFP_DMA | GFP_KERNEL);
158         }
159     } else if (streamType == AUDIO_RENDER_STREAM) {
160         if (data->renderBufInfo.virtAddr == NULL) {
161             preallocBufSize = data->renderBufInfo.cirBufMax;
162             dmaDevice->coherent_dma_mask = 0xffffffffUL;
163             AUDIO_DEVICE_LOG_DEBUG("AUDIO_RENDER_STREAM");
164             data->renderBufInfo.virtAddr = dma_alloc_wc(dmaDevice, preallocBufSize,
165                 (dma_addr_t *)&data->renderBufInfo.phyAddr, GFP_DMA | GFP_KERNEL);
166         }
167     } else {
168         AUDIO_DEVICE_LOG_ERR("stream Type is invalude.");
169         return HDF_FAILURE;
170     }
171 
172     AUDIO_DEVICE_LOG_DEBUG("success.");
173     return HDF_SUCCESS;
174 }
175 
Rk3588DmaBufFree(struct PlatformData *data, const enum AudioStreamType streamType)176 int32_t Rk3588DmaBufFree(struct PlatformData *data, const enum AudioStreamType streamType)
177 {
178     struct device *dmaDevice = getDmaDevice();
179 
180     if (data == NULL) {
181         AUDIO_DEVICE_LOG_ERR("data is null");
182         return HDF_FAILURE;
183     }
184 
185     if (streamType == AUDIO_CAPTURE_STREAM) {
186         AUDIO_DEVICE_LOG_DEBUG("AUDIO_CAPTURE_STREAM");
187         dma_free_wc(dmaDevice, data->captureBufInfo.cirBufMax, data->captureBufInfo.virtAddr,
188                     data->captureBufInfo.phyAddr);
189     } else if (streamType == AUDIO_RENDER_STREAM) {
190         AUDIO_DEVICE_LOG_DEBUG("AUDIO_RENDER_STREAM");
191         dma_free_wc(dmaDevice, data->renderBufInfo.cirBufMax, data->renderBufInfo.virtAddr,
192                     data->renderBufInfo.phyAddr);
193     } else {
194         AUDIO_DEVICE_LOG_ERR("stream Type is invalude.");
195         return HDF_FAILURE;
196     }
197 
198     AUDIO_DEVICE_LOG_DEBUG("success");
199     return HDF_SUCCESS;
200 }
201 
Rk3588DmaRequestChannel(const struct PlatformData *data, const enum AudioStreamType streamType)202 int32_t  Rk3588DmaRequestChannel(const struct PlatformData *data, const enum AudioStreamType streamType)
203 {
204     (void)data;
205     AUDIO_DEVICE_LOG_DEBUG("sucess");
206     return HDF_SUCCESS;
207 }
208 
Rk3588DmaConfigChannel(const struct PlatformData *data, const enum AudioStreamType streamType)209 int32_t Rk3588DmaConfigChannel(const struct PlatformData *data, const enum AudioStreamType streamType)
210 {
211     struct dma_chan *dmaChan;
212     struct dma_slave_config slaveConfig;
213     int32_t ret = 0;
214 
215     (void)memset_s(&slaveConfig, sizeof(slaveConfig), 0, sizeof(slaveConfig));
216     if (streamType == AUDIO_RENDER_STREAM) {
217         dmaChan = (struct dma_chan *)g_dmaChn[DMA_TX_CHANNEL];   // tx
218         slaveConfig.direction = DMA_MEM_TO_DEV;
219         slaveConfig.dst_addr_width = DMA_SLAVE_BUSWIDTH_4_BYTES;
220         slaveConfig.dst_addr = I2S0_ADDR + I2S_TXDR;
221         slaveConfig.dst_maxburst = 8; // Max Transimit 8 Byte
222     } else {
223         dmaChan = (struct dma_chan *)g_dmaChn[DMA_RX_CHANNEL];
224         slaveConfig.direction = DMA_DEV_TO_MEM;
225         slaveConfig.src_addr_width = DMA_SLAVE_BUSWIDTH_4_BYTES;
226         slaveConfig.src_addr = I2S0_ADDR + I2S_RXDR;
227         slaveConfig.src_maxburst = 8; // Max Transimit 8 Byte
228     }
229     slaveConfig.device_fc = 0;
230     slaveConfig.slave_id = 0;
231 
232     if (dmaChan == NULL) {
233         AUDIO_DEVICE_LOG_ERR("dmaChan is null");
234         return HDF_FAILURE;
235     }
236     ret = dmaengine_slave_config(dmaChan, &slaveConfig);
237     if (ret != 0) {
238         AUDIO_DEVICE_LOG_ERR("dmaengine_slave_config failed");
239         return HDF_FAILURE;
240     }
241     AUDIO_DEVICE_LOG_DEBUG("success");
242     return HDF_SUCCESS;
243 }
244 
BytesToFrames(uint32_t frameBits, uint32_t size, uint32_t *pointer)245 static int32_t BytesToFrames(uint32_t frameBits, uint32_t size, uint32_t *pointer)
246 {
247     if (pointer == NULL || frameBits == 0) {
248         AUDIO_DEVICE_LOG_ERR("input para is error.");
249         return HDF_FAILURE;
250     }
251     *pointer = size / frameBits;
252     return HDF_SUCCESS;
253 }
254 
Rk3588PcmPointer(struct PlatformData *data, const enum AudioStreamType streamType, uint32_t *pointer)255 int32_t Rk3588PcmPointer(struct PlatformData *data, const enum AudioStreamType streamType, uint32_t *pointer)
256 {
257     uint32_t bufSize;
258     struct dma_chan *dmaChn;
259     struct dma_tx_state dmaState;
260     uint32_t currentPointer;
261     int ret;
262 
263     if (data == NULL) {
264         AUDIO_DEVICE_LOG_ERR("input para is null.");
265         return HDF_FAILURE;
266     }
267 
268     if (streamType == AUDIO_RENDER_STREAM) {
269         dmaChn = g_dmaChn[DMA_TX_CHANNEL];
270         bufSize = data->renderBufInfo.cirBufSize;
271         if (dmaChn == NULL) {
272             AUDIO_DEVICE_LOG_ERR("dmaChan is null");
273             return HDF_FAILURE;
274         }
275         dmaengine_tx_status(dmaChn, g_cookie[DMA_TX_CHANNEL], &dmaState);
276 
277         if (dmaState.residue) {
278             currentPointer = bufSize - dmaState.residue;
279             ret = BytesToFrames(data->renderPcmInfo.frameSize, currentPointer, pointer);
280             if (ret != HDF_SUCCESS) {
281                 AUDIO_DEVICE_LOG_ERR("BytesToFrames is failed.");
282                 return HDF_FAILURE;
283             }
284         } else {
285             *pointer = 0;
286         }
287     } else {
288         dmaChn = g_dmaChn[DMA_RX_CHANNEL];
289         bufSize = data->captureBufInfo.cirBufSize;
290         if (dmaChn == NULL) {
291             AUDIO_DEVICE_LOG_ERR("dmaChan is null");
292             return HDF_FAILURE;
293         }
294         dmaengine_tx_status(dmaChn, g_cookie[DMA_RX_CHANNEL], &dmaState);
295 
296         if (dmaState.residue) {
297             currentPointer = bufSize - dmaState.residue;
298             ret = BytesToFrames(data->capturePcmInfo.frameSize, currentPointer, pointer);
299             if (ret != HDF_SUCCESS) {
300                 AUDIO_DEVICE_LOG_ERR("BytesToFrames is failed.");
301                 return HDF_FAILURE;
302             }
303         } else {
304             *pointer = 0;
305         }
306     }
307 
308     return HDF_SUCCESS;
309 }
310 
Rk3588DmaPrep(const struct PlatformData *data, const enum AudioStreamType streamType)311 int32_t Rk3588DmaPrep(const struct PlatformData *data, const enum AudioStreamType streamType)
312 {
313     (void)data;
314     return HDF_SUCCESS;
315 }
316 
317 
318 
Rk3588DmaSubmit(const struct PlatformData *data, const enum AudioStreamType streamType)319 int32_t Rk3588DmaSubmit(const struct PlatformData *data, const enum AudioStreamType streamType)
320 {
321     struct dma_async_tx_descriptor *desc;
322     enum dma_transfer_direction direction;
323     unsigned long flags = 3;
324     struct dma_chan *dmaChan = NULL;
325 
326     if (data == NULL) {
327         AUDIO_DEVICE_LOG_ERR("input para is null.");
328         return HDF_FAILURE;
329     }
330 
331     if (streamType == AUDIO_RENDER_STREAM) {
332         direction = DMA_MEM_TO_DEV;
333         dmaChan = g_dmaChn[DMA_TX_CHANNEL];
334         if (dmaChan == NULL) {
335             AUDIO_DEVICE_LOG_ERR("dmaChan is null");
336             return HDF_FAILURE;
337         }
338         desc = dmaengine_prep_dma_cyclic(dmaChan,
339             data->renderBufInfo.phyAddr,
340             data->renderBufInfo.cirBufSize,
341             data->renderBufInfo.periodSize, direction, flags);
342         if (!desc) {
343             AUDIO_DEVICE_LOG_ERR("DMA_TX_CHANNEL desc create failed");
344             return -ENOMEM;
345         }
346         g_cookie[DMA_TX_CHANNEL] = dmaengine_submit(desc);
347     } else {
348         direction = DMA_DEV_TO_MEM;
349         dmaChan = g_dmaChn[DMA_RX_CHANNEL];
350         if (dmaChan == NULL) {
351             AUDIO_DEVICE_LOG_ERR("dmaChan is null");
352             return HDF_FAILURE;
353         }
354 
355         desc = dmaengine_prep_dma_cyclic(dmaChan,
356             data->captureBufInfo.phyAddr,
357             data->captureBufInfo.cirBufSize,
358             data->captureBufInfo.periodSize, direction, flags);
359         if (!desc) {
360             AUDIO_DEVICE_LOG_ERR("DMA_RX_CHANNEL desc create failed");
361             return -ENOMEM;
362         }
363 
364         g_cookie[DMA_RX_CHANNEL] = dmaengine_submit(desc);
365     }
366 
367     AUDIO_DEVICE_LOG_DEBUG("success");
368     return 0;
369 }
370 
Rk3588DmaPending(struct PlatformData *data, const enum AudioStreamType streamType)371 int32_t Rk3588DmaPending(struct PlatformData *data, const enum AudioStreamType streamType)
372 {
373     struct dma_chan *dmaChan = NULL;
374 
375     AUDIO_DEVICE_LOG_DEBUG("streamType = %d", streamType);
376     if (streamType == AUDIO_RENDER_STREAM) {
377         dmaChan = g_dmaChn[DMA_TX_CHANNEL];
378     } else {
379         dmaChan = g_dmaChn[DMA_RX_CHANNEL];
380     }
381     if (dmaChan == NULL) {
382         AUDIO_DEVICE_LOG_ERR("dmaChan is null");
383         return HDF_FAILURE;
384     }
385 
386     dma_async_issue_pending(dmaChan);
387     AUDIO_DEVICE_LOG_DEBUG("dmaChan chan_id = %d.", dmaChan->chan_id);
388 
389     AUDIO_DEVICE_LOG_DEBUG("success");
390     return HDF_SUCCESS;
391 }
392 
Rk3588DmaPause(struct PlatformData *data, const enum AudioStreamType streamType)393 int32_t Rk3588DmaPause(struct PlatformData *data, const enum AudioStreamType streamType)
394 {
395     struct dma_chan *dmaChan;
396 
397     if (streamType == AUDIO_RENDER_STREAM) {
398         dmaChan = g_dmaChn[DMA_TX_CHANNEL];
399     } else {
400         dmaChan = g_dmaChn[DMA_RX_CHANNEL];
401     }
402     // can not use dmaengine_pause function
403     if (dmaChan == NULL) {
404         AUDIO_DEVICE_LOG_ERR("dmaChan is null");
405         return HDF_FAILURE;
406     }
407     dmaengine_terminate_async(dmaChan);
408 
409     AUDIO_DEVICE_LOG_DEBUG("success");
410     return HDF_SUCCESS;
411 }
Rk3588DmaResume(const struct PlatformData *data, const enum AudioStreamType streamType)412 int32_t Rk3588DmaResume(const struct PlatformData *data, const enum AudioStreamType streamType)
413 {
414     int ret;
415     struct dma_chan *dmaChan;
416     if (data == NULL) {
417         AUDIO_DEVICE_LOG_ERR("data is null");
418         return HDF_FAILURE;
419     }
420 
421     if (streamType == AUDIO_RENDER_STREAM) {
422         dmaChan = g_dmaChn[DMA_TX_CHANNEL];
423     } else {
424         dmaChan = g_dmaChn[DMA_RX_CHANNEL];
425     }
426     if (dmaChan == NULL) {
427         AUDIO_DEVICE_LOG_ERR("dmaChan is null");
428         return HDF_FAILURE;
429     }
430 
431     // use start Operation function
432     ret = Rk3588DmaSubmit(data, streamType);
433     if (ret != HDF_SUCCESS) {
434         AUDIO_DEVICE_LOG_ERR("call Rk3588DmaSubmit failed");
435         return HDF_FAILURE;
436     }
437     dma_async_issue_pending(dmaChan);
438 
439     AUDIO_DEVICE_LOG_DEBUG("success");
440     return HDF_SUCCESS;
441 }
442