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