forked from ~ljy/RK356X_SDK_RELEASE

hc
2024-01-31 f70575805708cabdedea7498aaa3f710fde4d920
kernel/sound/soc/fsl/fsl_asrc_dma.c
....@@ -12,17 +12,15 @@
1212 #include <sound/dmaengine_pcm.h>
1313 #include <sound/pcm_params.h>
1414
15
-#include "fsl_asrc.h"
15
+#include "fsl_asrc_common.h"
1616
1717 #define FSL_ASRC_DMABUF_SIZE (256 * 1024)
1818
19
-static const struct snd_pcm_hardware snd_imx_hardware = {
19
+static struct snd_pcm_hardware snd_imx_hardware = {
2020 .info = SNDRV_PCM_INFO_INTERLEAVED |
2121 SNDRV_PCM_INFO_BLOCK_TRANSFER |
2222 SNDRV_PCM_INFO_MMAP |
23
- SNDRV_PCM_INFO_MMAP_VALID |
24
- SNDRV_PCM_INFO_PAUSE |
25
- SNDRV_PCM_INFO_RESUME,
23
+ SNDRV_PCM_INFO_MMAP_VALID,
2624 .buffer_bytes_max = FSL_ASRC_DMABUF_SIZE,
2725 .period_bytes_min = 128,
2826 .period_bytes_max = 65535, /* Limited by SDMA engine */
....@@ -54,13 +52,12 @@
5452 snd_pcm_period_elapsed(substream);
5553 }
5654
57
-static int fsl_asrc_dma_prepare_and_submit(struct snd_pcm_substream *substream)
55
+static int fsl_asrc_dma_prepare_and_submit(struct snd_pcm_substream *substream,
56
+ struct snd_soc_component *component)
5857 {
5958 u8 dir = substream->stream == SNDRV_PCM_STREAM_PLAYBACK ? OUT : IN;
60
- struct snd_soc_pcm_runtime *rtd = substream->private_data;
6159 struct snd_pcm_runtime *runtime = substream->runtime;
6260 struct fsl_asrc_pair *pair = runtime->private_data;
63
- struct snd_soc_component *component = snd_soc_rtdcom_lookup(rtd, DRV_NAME);
6461 struct device *dev = component->dev;
6562 unsigned long flags = DMA_CTRL_ACK;
6663
....@@ -97,7 +94,8 @@
9794 return 0;
9895 }
9996
100
-static int fsl_asrc_dma_trigger(struct snd_pcm_substream *substream, int cmd)
97
+static int fsl_asrc_dma_trigger(struct snd_soc_component *component,
98
+ struct snd_pcm_substream *substream, int cmd)
10199 {
102100 struct snd_pcm_runtime *runtime = substream->runtime;
103101 struct fsl_asrc_pair *pair = runtime->private_data;
....@@ -107,7 +105,7 @@
107105 case SNDRV_PCM_TRIGGER_START:
108106 case SNDRV_PCM_TRIGGER_RESUME:
109107 case SNDRV_PCM_TRIGGER_PAUSE_RELEASE:
110
- ret = fsl_asrc_dma_prepare_and_submit(substream);
108
+ ret = fsl_asrc_dma_prepare_and_submit(substream, component);
111109 if (ret)
112110 return ret;
113111 dma_async_issue_pending(pair->dma_chan[IN]);
....@@ -126,35 +124,36 @@
126124 return 0;
127125 }
128126
129
-static int fsl_asrc_dma_hw_params(struct snd_pcm_substream *substream,
127
+static int fsl_asrc_dma_hw_params(struct snd_soc_component *component,
128
+ struct snd_pcm_substream *substream,
130129 struct snd_pcm_hw_params *params)
131130 {
132131 enum dma_slave_buswidth buswidth = DMA_SLAVE_BUSWIDTH_2_BYTES;
133
- struct snd_soc_pcm_runtime *rtd = substream->private_data;
132
+ struct snd_soc_pcm_runtime *rtd = asoc_substream_to_rtd(substream);
134133 bool tx = substream->stream == SNDRV_PCM_STREAM_PLAYBACK;
135134 struct snd_dmaengine_dai_dma_data *dma_params_fe = NULL;
136135 struct snd_dmaengine_dai_dma_data *dma_params_be = NULL;
137
- struct snd_soc_component *component = snd_soc_rtdcom_lookup(rtd, DRV_NAME);
138136 struct snd_pcm_runtime *runtime = substream->runtime;
139137 struct fsl_asrc_pair *pair = runtime->private_data;
140
- struct fsl_asrc *asrc_priv = pair->asrc_priv;
138
+ struct dma_chan *tmp_chan = NULL, *be_chan = NULL;
139
+ struct snd_soc_component *component_be = NULL;
140
+ struct fsl_asrc *asrc = pair->asrc;
141141 struct dma_slave_config config_fe, config_be;
142142 enum asrc_pair_index index = pair->index;
143143 struct device *dev = component->dev;
144144 int stream = substream->stream;
145145 struct imx_dma_data *tmp_data;
146146 struct snd_soc_dpcm *dpcm;
147
- struct dma_chan *tmp_chan;
148147 struct device *dev_be;
149148 u8 dir = tx ? OUT : IN;
150149 dma_cap_mask_t mask;
151
- int ret;
150
+ int ret, width;
152151
153152 /* Fetch the Back-End dma_data from DPCM */
154
- list_for_each_entry(dpcm, &rtd->dpcm[stream].be_clients, list_be) {
153
+ for_each_dpcm_be(rtd, stream, dpcm) {
155154 struct snd_soc_pcm_runtime *be = dpcm->be;
156155 struct snd_pcm_substream *substream_be;
157
- struct snd_soc_dai *dai = be->cpu_dai;
156
+ struct snd_soc_dai *dai = asoc_rtd_to_cpu(be, 0);
158157
159158 if (dpcm->fe != rtd)
160159 continue;
....@@ -171,11 +170,11 @@
171170 }
172171
173172 /* Override dma_data of the Front-End and config its dmaengine */
174
- dma_params_fe = snd_soc_dai_get_dma_data(rtd->cpu_dai, substream);
175
- dma_params_fe->addr = asrc_priv->paddr + REG_ASRDx(!dir, index);
173
+ dma_params_fe = snd_soc_dai_get_dma_data(asoc_rtd_to_cpu(rtd, 0), substream);
174
+ dma_params_fe->addr = asrc->paddr + asrc->get_fifo_addr(!dir, index);
176175 dma_params_fe->maxburst = dma_params_be->maxburst;
177176
178
- pair->dma_chan[!dir] = fsl_asrc_get_dma_channel(pair, !dir);
177
+ pair->dma_chan[!dir] = asrc->get_dma_channel(pair, !dir);
179178 if (!pair->dma_chan[!dir]) {
180179 dev_err(dev, "failed to request DMA channel\n");
181180 return -EINVAL;
....@@ -199,30 +198,71 @@
199198 dma_cap_set(DMA_SLAVE, mask);
200199 dma_cap_set(DMA_CYCLIC, mask);
201200
202
- /* Get DMA request of Back-End */
203
- tmp_chan = dma_request_slave_channel(dev_be, tx ? "tx" : "rx");
204
- tmp_data = tmp_chan->private;
205
- pair->dma_data.dma_request = tmp_data->dma_request;
206
- dma_release_channel(tmp_chan);
201
+ /*
202
+ * The Back-End device might have already requested a DMA channel,
203
+ * so try to reuse it first, and then request a new one upon NULL.
204
+ */
205
+ component_be = snd_soc_lookup_component_nolocked(dev_be, SND_DMAENGINE_PCM_DRV_NAME);
206
+ if (component_be) {
207
+ be_chan = soc_component_to_pcm(component_be)->chan[substream->stream];
208
+ tmp_chan = be_chan;
209
+ }
210
+ if (!tmp_chan) {
211
+ tmp_chan = dma_request_chan(dev_be, tx ? "tx" : "rx");
212
+ if (IS_ERR(tmp_chan)) {
213
+ dev_err(dev, "failed to request DMA channel for Back-End\n");
214
+ return -EINVAL;
215
+ }
216
+ }
207217
208
- /* Get DMA request of Front-End */
209
- tmp_chan = fsl_asrc_get_dma_channel(pair, dir);
210
- tmp_data = tmp_chan->private;
211
- pair->dma_data.dma_request2 = tmp_data->dma_request;
212
- pair->dma_data.peripheral_type = tmp_data->peripheral_type;
213
- pair->dma_data.priority = tmp_data->priority;
214
- dma_release_channel(tmp_chan);
218
+ /*
219
+ * An EDMA DEV_TO_DEV channel is fixed and bound with DMA event of each
220
+ * peripheral, unlike SDMA channel that is allocated dynamically. So no
221
+ * need to configure dma_request and dma_request2, but get dma_chan of
222
+ * Back-End device directly via dma_request_chan.
223
+ */
224
+ if (!asrc->use_edma) {
225
+ /* Get DMA request of Back-End */
226
+ tmp_data = tmp_chan->private;
227
+ pair->dma_data.dma_request = tmp_data->dma_request;
228
+ if (!be_chan)
229
+ dma_release_channel(tmp_chan);
215230
216
- pair->dma_chan[dir] = dma_request_channel(mask, filter, &pair->dma_data);
231
+ /* Get DMA request of Front-End */
232
+ tmp_chan = asrc->get_dma_channel(pair, dir);
233
+ tmp_data = tmp_chan->private;
234
+ pair->dma_data.dma_request2 = tmp_data->dma_request;
235
+ pair->dma_data.peripheral_type = tmp_data->peripheral_type;
236
+ pair->dma_data.priority = tmp_data->priority;
237
+ dma_release_channel(tmp_chan);
238
+
239
+ pair->dma_chan[dir] =
240
+ dma_request_channel(mask, filter, &pair->dma_data);
241
+ pair->req_dma_chan = true;
242
+ } else {
243
+ pair->dma_chan[dir] = tmp_chan;
244
+ /* Do not flag to release if we are reusing the Back-End one */
245
+ pair->req_dma_chan = !be_chan;
246
+ }
247
+
217248 if (!pair->dma_chan[dir]) {
218249 dev_err(dev, "failed to request DMA channel for Back-End\n");
219250 return -EINVAL;
220251 }
221252
222
- if (asrc_priv->asrc_width == 16)
253
+ width = snd_pcm_format_physical_width(asrc->asrc_format);
254
+ if (width < 8 || width > 64)
255
+ return -EINVAL;
256
+ else if (width == 8)
257
+ buswidth = DMA_SLAVE_BUSWIDTH_1_BYTE;
258
+ else if (width == 16)
223259 buswidth = DMA_SLAVE_BUSWIDTH_2_BYTES;
224
- else
260
+ else if (width == 24)
261
+ buswidth = DMA_SLAVE_BUSWIDTH_3_BYTES;
262
+ else if (width <= 32)
225263 buswidth = DMA_SLAVE_BUSWIDTH_4_BYTES;
264
+ else
265
+ buswidth = DMA_SLAVE_BUSWIDTH_8_BYTES;
226266
227267 config_be.direction = DMA_DEV_TO_DEV;
228268 config_be.src_addr_width = buswidth;
....@@ -231,17 +271,18 @@
231271 config_be.dst_maxburst = dma_params_be->maxburst;
232272
233273 if (tx) {
234
- config_be.src_addr = asrc_priv->paddr + REG_ASRDO(index);
274
+ config_be.src_addr = asrc->paddr + asrc->get_fifo_addr(OUT, index);
235275 config_be.dst_addr = dma_params_be->addr;
236276 } else {
237
- config_be.dst_addr = asrc_priv->paddr + REG_ASRDI(index);
277
+ config_be.dst_addr = asrc->paddr + asrc->get_fifo_addr(IN, index);
238278 config_be.src_addr = dma_params_be->addr;
239279 }
240280
241281 ret = dmaengine_slave_config(pair->dma_chan[dir], &config_be);
242282 if (ret) {
243283 dev_err(dev, "failed to config DMA channel for Back-End\n");
244
- dma_release_channel(pair->dma_chan[dir]);
284
+ if (pair->req_dma_chan)
285
+ dma_release_channel(pair->dma_chan[dir]);
245286 return ret;
246287 }
247288
....@@ -250,69 +291,129 @@
250291 return 0;
251292 }
252293
253
-static int fsl_asrc_dma_hw_free(struct snd_pcm_substream *substream)
294
+static int fsl_asrc_dma_hw_free(struct snd_soc_component *component,
295
+ struct snd_pcm_substream *substream)
254296 {
297
+ bool tx = substream->stream == SNDRV_PCM_STREAM_PLAYBACK;
255298 struct snd_pcm_runtime *runtime = substream->runtime;
256299 struct fsl_asrc_pair *pair = runtime->private_data;
300
+ u8 dir = tx ? OUT : IN;
257301
258302 snd_pcm_set_runtime_buffer(substream, NULL);
259303
260
- if (pair->dma_chan[IN])
261
- dma_release_channel(pair->dma_chan[IN]);
304
+ if (pair->dma_chan[!dir])
305
+ dma_release_channel(pair->dma_chan[!dir]);
262306
263
- if (pair->dma_chan[OUT])
264
- dma_release_channel(pair->dma_chan[OUT]);
307
+ /* release dev_to_dev chan if we aren't reusing the Back-End one */
308
+ if (pair->dma_chan[dir] && pair->req_dma_chan)
309
+ dma_release_channel(pair->dma_chan[dir]);
265310
266
- pair->dma_chan[IN] = NULL;
267
- pair->dma_chan[OUT] = NULL;
311
+ pair->dma_chan[!dir] = NULL;
312
+ pair->dma_chan[dir] = NULL;
268313
269314 return 0;
270315 }
271316
272
-static int fsl_asrc_dma_startup(struct snd_pcm_substream *substream)
317
+static int fsl_asrc_dma_startup(struct snd_soc_component *component,
318
+ struct snd_pcm_substream *substream)
273319 {
274
- struct snd_soc_pcm_runtime *rtd = substream->private_data;
320
+ bool tx = substream->stream == SNDRV_PCM_STREAM_PLAYBACK;
321
+ struct snd_soc_pcm_runtime *rtd = asoc_substream_to_rtd(substream);
275322 struct snd_pcm_runtime *runtime = substream->runtime;
276
- struct snd_soc_component *component = snd_soc_rtdcom_lookup(rtd, DRV_NAME);
323
+ struct snd_dmaengine_dai_dma_data *dma_data;
277324 struct device *dev = component->dev;
278
- struct fsl_asrc *asrc_priv = dev_get_drvdata(dev);
325
+ struct fsl_asrc *asrc = dev_get_drvdata(dev);
279326 struct fsl_asrc_pair *pair;
327
+ struct dma_chan *tmp_chan = NULL;
328
+ u8 dir = tx ? OUT : IN;
329
+ bool release_pair = true;
330
+ int ret = 0;
280331
281
- pair = kzalloc(sizeof(struct fsl_asrc_pair), GFP_KERNEL);
332
+ ret = snd_pcm_hw_constraint_integer(substream->runtime,
333
+ SNDRV_PCM_HW_PARAM_PERIODS);
334
+ if (ret < 0) {
335
+ dev_err(dev, "failed to set pcm hw params periods\n");
336
+ return ret;
337
+ }
338
+
339
+ pair = kzalloc(sizeof(*pair) + asrc->pair_priv_size, GFP_KERNEL);
282340 if (!pair)
283341 return -ENOMEM;
284342
285
- pair->asrc_priv = asrc_priv;
343
+ pair->asrc = asrc;
344
+ pair->private = (void *)pair + sizeof(struct fsl_asrc_pair);
286345
287346 runtime->private_data = pair;
288347
289
- snd_pcm_hw_constraint_integer(substream->runtime,
290
- SNDRV_PCM_HW_PARAM_PERIODS);
348
+ /* Request a dummy pair, which will be released later.
349
+ * Request pair function needs channel num as input, for this
350
+ * dummy pair, we just request "1" channel temporarily.
351
+ */
352
+ ret = asrc->request_pair(1, pair);
353
+ if (ret < 0) {
354
+ dev_err(dev, "failed to request asrc pair\n");
355
+ goto req_pair_err;
356
+ }
357
+
358
+ /* Request a dummy dma channel, which will be released later. */
359
+ tmp_chan = asrc->get_dma_channel(pair, dir);
360
+ if (!tmp_chan) {
361
+ dev_err(dev, "failed to get dma channel\n");
362
+ ret = -EINVAL;
363
+ goto dma_chan_err;
364
+ }
365
+
366
+ dma_data = snd_soc_dai_get_dma_data(asoc_rtd_to_cpu(rtd, 0), substream);
367
+
368
+ /* Refine the snd_imx_hardware according to caps of DMA. */
369
+ ret = snd_dmaengine_pcm_refine_runtime_hwparams(substream,
370
+ dma_data,
371
+ &snd_imx_hardware,
372
+ tmp_chan);
373
+ if (ret < 0) {
374
+ dev_err(dev, "failed to refine runtime hwparams\n");
375
+ goto out;
376
+ }
377
+
378
+ release_pair = false;
291379 snd_soc_set_runtime_hwparams(substream, &snd_imx_hardware);
292380
293
- return 0;
381
+out:
382
+ dma_release_channel(tmp_chan);
383
+
384
+dma_chan_err:
385
+ asrc->release_pair(pair);
386
+
387
+req_pair_err:
388
+ if (release_pair)
389
+ kfree(pair);
390
+
391
+ return ret;
294392 }
295393
296
-static int fsl_asrc_dma_shutdown(struct snd_pcm_substream *substream)
394
+static int fsl_asrc_dma_shutdown(struct snd_soc_component *component,
395
+ struct snd_pcm_substream *substream)
297396 {
298397 struct snd_pcm_runtime *runtime = substream->runtime;
299398 struct fsl_asrc_pair *pair = runtime->private_data;
300
- struct fsl_asrc *asrc_priv;
399
+ struct fsl_asrc *asrc;
301400
302401 if (!pair)
303402 return 0;
304403
305
- asrc_priv = pair->asrc_priv;
404
+ asrc = pair->asrc;
306405
307
- if (asrc_priv->pair[pair->index] == pair)
308
- asrc_priv->pair[pair->index] = NULL;
406
+ if (asrc->pair[pair->index] == pair)
407
+ asrc->pair[pair->index] = NULL;
309408
310409 kfree(pair);
311410
312411 return 0;
313412 }
314413
315
-static snd_pcm_uframes_t fsl_asrc_dma_pcm_pointer(struct snd_pcm_substream *substream)
414
+static snd_pcm_uframes_t
415
+fsl_asrc_dma_pcm_pointer(struct snd_soc_component *component,
416
+ struct snd_pcm_substream *substream)
316417 {
317418 struct snd_pcm_runtime *runtime = substream->runtime;
318419 struct fsl_asrc_pair *pair = runtime->private_data;
....@@ -320,17 +421,8 @@
320421 return bytes_to_frames(substream->runtime, pair->pos);
321422 }
322423
323
-static const struct snd_pcm_ops fsl_asrc_dma_pcm_ops = {
324
- .ioctl = snd_pcm_lib_ioctl,
325
- .hw_params = fsl_asrc_dma_hw_params,
326
- .hw_free = fsl_asrc_dma_hw_free,
327
- .trigger = fsl_asrc_dma_trigger,
328
- .open = fsl_asrc_dma_startup,
329
- .close = fsl_asrc_dma_shutdown,
330
- .pointer = fsl_asrc_dma_pcm_pointer,
331
-};
332
-
333
-static int fsl_asrc_dma_pcm_new(struct snd_soc_pcm_runtime *rtd)
424
+static int fsl_asrc_dma_pcm_new(struct snd_soc_component *component,
425
+ struct snd_soc_pcm_runtime *rtd)
334426 {
335427 struct snd_card *card = rtd->card->snd_card;
336428 struct snd_pcm_substream *substream;
....@@ -343,7 +435,7 @@
343435 return ret;
344436 }
345437
346
- for (i = SNDRV_PCM_STREAM_PLAYBACK; i <= SNDRV_PCM_STREAM_LAST; i++) {
438
+ for_each_pcm_streams(i) {
347439 substream = pcm->streams[i].substream;
348440 if (!substream)
349441 continue;
....@@ -365,12 +457,13 @@
365457 return ret;
366458 }
367459
368
-static void fsl_asrc_dma_pcm_free(struct snd_pcm *pcm)
460
+static void fsl_asrc_dma_pcm_free(struct snd_soc_component *component,
461
+ struct snd_pcm *pcm)
369462 {
370463 struct snd_pcm_substream *substream;
371464 int i;
372465
373
- for (i = SNDRV_PCM_STREAM_PLAYBACK; i <= SNDRV_PCM_STREAM_LAST; i++) {
466
+ for_each_pcm_streams(i) {
374467 substream = pcm->streams[i].substream;
375468 if (!substream)
376469 continue;
....@@ -383,8 +476,13 @@
383476
384477 struct snd_soc_component_driver fsl_asrc_component = {
385478 .name = DRV_NAME,
386
- .ops = &fsl_asrc_dma_pcm_ops,
387
- .pcm_new = fsl_asrc_dma_pcm_new,
388
- .pcm_free = fsl_asrc_dma_pcm_free,
479
+ .hw_params = fsl_asrc_dma_hw_params,
480
+ .hw_free = fsl_asrc_dma_hw_free,
481
+ .trigger = fsl_asrc_dma_trigger,
482
+ .open = fsl_asrc_dma_startup,
483
+ .close = fsl_asrc_dma_shutdown,
484
+ .pointer = fsl_asrc_dma_pcm_pointer,
485
+ .pcm_construct = fsl_asrc_dma_pcm_new,
486
+ .pcm_destruct = fsl_asrc_dma_pcm_free,
389487 };
390488 EXPORT_SYMBOL_GPL(fsl_asrc_component);