Skip to content

Commit f26c7bb

Browse files
committed
audio: dai-zephyr: rework calls to DMA driver, remove channel pointer
For historical reasons, dai-zephyr has somewhat complicated code to manage the DMA channel instance information. When a DMA channel is allocated, a pointer to the system DMA channel table is acquired and some additional information is stored per channel. This is however redundant as the only piece of information actually needed is the channel index. Simplify the code by not storing the channel pointer anymore, but rather just store the channel index and use that in all calls to the DMA driver. Signed-off-by: Kai Vehmanen <kai.vehmanen@linux.intel.com>
1 parent 32ca17f commit f26c7bb

4 files changed

Lines changed: 55 additions & 60 deletions

File tree

src/audio/dai-zephyr.c

Lines changed: 31 additions & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -516,6 +516,7 @@ __cold int dai_common_new(struct dai_data *dd, struct comp_dev *dev,
516516
dir = dai_cfg->direction == SOF_IPC_STREAM_PLAYBACK ?
517517
SOF_DMA_DIR_MEM_TO_DEV : SOF_DMA_DIR_DEV_TO_MEM;
518518

519+
dd->chan_index = -EINVAL;
519520
dd->dma = sof_dma_get(dir, dd->dai->dma_caps, dd->dai->dma_dev, SOF_DMA_ACCESS_SHARED);
520521
if (!dd->dma) {
521522
dai_put(dd->dai);
@@ -527,7 +528,6 @@ __cold int dai_common_new(struct dai_data *dd, struct comp_dev *dev,
527528

528529
dma_sg_init(&dd->config.elem_array);
529530
dd->xrun = 0;
530-
dd->chan = NULL;
531531

532532
/* I/O performance init, keep it last so the function does not reach this in case
533533
* of return on error, so that we do not waste a slot
@@ -627,9 +627,9 @@ __cold void dai_common_free(struct dai_data *dd)
627627
if (dd->group)
628628
dai_group_put(dd->group);
629629

630-
if (dd->chan) {
631-
sof_dma_release_channel(dd->dma, dd->chan->index);
632-
dd->chan->dev_data = NULL;
630+
if (dd->chan_index >= 0) {
631+
sof_dma_release_channel(dd->dma, dd->chan_index);
632+
dd->chan_index = -EINVAL;
633633
}
634634

635635
sof_dma_put(dd->dma);
@@ -1160,9 +1160,9 @@ int dai_common_config_prepare(struct dai_data *dd, struct comp_dev *dev)
11601160
return -EINVAL;
11611161
}
11621162

1163-
if (dd->chan) {
1163+
if (dd->chan_index >= 0) {
11641164
comp_info(dev, "dma channel index %d already configured",
1165-
dd->chan->index);
1165+
dd->chan_index);
11661166
return 0;
11671167
}
11681168

@@ -1176,18 +1176,14 @@ int dai_common_config_prepare(struct dai_data *dd, struct comp_dev *dev)
11761176
}
11771177

11781178
/* get DMA channel */
1179-
channel = sof_dma_request_channel(dd->dma, channel);
1180-
if (channel < 0) {
1181-
comp_err(dev, "dma_request_channel() failed");
1182-
dd->chan = NULL;
1183-
return -EIO;
1179+
dd->chan_index = sof_dma_request_channel(dd->dma, channel);
1180+
if (dd->chan_index < 0) {
1181+
comp_err(dev, "dma_request_channel() failed ch %d ret %d", channel, dd->chan_index);
1182+
return dd->chan_index;
11841183
}
11851184

1186-
dd->chan = &dd->dma->chan[channel];
1187-
dd->chan->dev_data = dd;
1188-
11891185
comp_dbg(dev, "new configured dma channel index %d",
1190-
dd->chan->index);
1186+
dd->chan_index);
11911187

11921188
return 0;
11931189
}
@@ -1198,8 +1194,8 @@ int dai_common_prepare(struct dai_data *dd, struct comp_dev *dev)
11981194

11991195
dd->total_data_processed = 0;
12001196

1201-
if (!dd->chan) {
1202-
comp_err(dev, "Missing dd->chan.");
1197+
if (dd->chan_index < 0) {
1198+
comp_err(dev, "Missing dd->chan_index.");
12031199
comp_set_state(dev, COMP_TRIGGER_RESET);
12041200
return -EINVAL;
12051201
}
@@ -1220,7 +1216,7 @@ int dai_common_prepare(struct dai_data *dd, struct comp_dev *dev)
12201216
return 0;
12211217
}
12221218

1223-
ret = sof_dma_config(dd->chan->dma, dd->chan->index, dd->z_config);
1219+
ret = sof_dma_config(dd->dma, dd->chan_index, dd->z_config);
12241220
if (ret < 0)
12251221
comp_set_state(dev, COMP_TRIGGER_RESET);
12261222

@@ -1307,7 +1303,7 @@ static int dai_comp_trigger_internal(struct dai_data *dd, struct comp_dev *dev,
13071303

13081304
/* only start the DAI if we are not XRUN handling */
13091305
if (dd->xrun == 0) {
1310-
ret = sof_dma_start(dd->chan->dma, dd->chan->index);
1306+
ret = sof_dma_start(dd->dma, dd->chan_index);
13111307
if (ret < 0)
13121308
return ret;
13131309

@@ -1345,16 +1341,16 @@ static int dai_comp_trigger_internal(struct dai_data *dd, struct comp_dev *dev,
13451341
/* only start the DAI if we are not XRUN handling */
13461342
if (dd->xrun == 0) {
13471343
/* recover valid start position */
1348-
ret = sof_dma_stop(dd->chan->dma, dd->chan->index);
1344+
ret = sof_dma_stop(dd->dma, dd->chan_index);
13491345
if (ret < 0)
13501346
return ret;
13511347

13521348
/* dma_config needed after stop */
1353-
ret = sof_dma_config(dd->chan->dma, dd->chan->index, dd->z_config);
1349+
ret = sof_dma_config(dd->dma, dd->chan_index, dd->z_config);
13541350
if (ret < 0)
13551351
return ret;
13561352

1357-
ret = sof_dma_start(dd->chan->dma, dd->chan->index);
1353+
ret = sof_dma_start(dd->dma, dd->chan_index);
13581354
if (ret < 0)
13591355
return ret;
13601356

@@ -1382,11 +1378,11 @@ static int dai_comp_trigger_internal(struct dai_data *dd, struct comp_dev *dev,
13821378
* as soon as possible.
13831379
*/
13841380
#if CONFIG_COMP_DAI_STOP_TRIGGER_ORDER_REVERSE
1385-
ret = sof_dma_stop(dd->chan->dma, dd->chan->index);
1381+
ret = sof_dma_stop(dd->dma, dd->chan_index);
13861382
dai_trigger_op(dd->dai, cmd, dev->direction);
13871383
#else
13881384
dai_trigger_op(dd->dai, cmd, dev->direction);
1389-
ret = sof_dma_stop(dd->chan->dma, dd->chan->index);
1385+
ret = sof_dma_stop(dd->dma, dd->chan_index);
13901386
if (ret) {
13911387
comp_warn(dev, "dma was stopped earlier");
13921388
ret = 0;
@@ -1396,11 +1392,11 @@ static int dai_comp_trigger_internal(struct dai_data *dd, struct comp_dev *dev,
13961392
case COMP_TRIGGER_PAUSE:
13971393
comp_dbg(dev, "PAUSE");
13981394
#if CONFIG_COMP_DAI_STOP_TRIGGER_ORDER_REVERSE
1399-
ret = sof_dma_suspend(dd->chan->dma, dd->chan->index);
1395+
ret = sof_dma_suspend(dd->dma, dd->chan_index);
14001396
dai_trigger_op(dd->dai, cmd, dev->direction);
14011397
#else
14021398
dai_trigger_op(dd->dai, cmd, dev->direction);
1403-
ret = sof_dma_suspend(dd->chan->dma, dd->chan->index);
1399+
ret = sof_dma_suspend(dd->dma, dd->chan_index);
14041400
#endif
14051401
break;
14061402
case COMP_TRIGGER_PRE_START:
@@ -1498,7 +1494,7 @@ static int dai_comp_trigger(struct comp_dev *dev, int cmd)
14981494
*/
14991495
static int dai_get_status(struct comp_dev *dev, struct dai_data *dd, struct dma_status *stat)
15001496
{
1501-
int ret = sof_dma_get_status(dd->chan->dma, dd->chan->index, stat);
1497+
int ret = sof_dma_get_status(dd->dma, dd->chan_index, stat);
15021498
#if CONFIG_XRUN_NOTIFICATIONS_ENABLE
15031499
if (ret == -EPIPE && !dd->xrun_notification_sent) {
15041500
dd->xrun_notification_sent = send_copier_gateway_xrun_notif_msg
@@ -1603,7 +1599,7 @@ int dai_zephyr_multi_endpoint_copy(struct dai_data **dd, struct comp_dev *dev,
16031599
#endif
16041600

16051601
for (i = 0; i < num_endpoints; i++) {
1606-
ret = sof_dma_reload(dd[i]->chan->dma, dd[i]->chan->index, 0);
1602+
ret = sof_dma_reload(dd[i]->dma, dd[i]->chan_index, 0);
16071603
if (ret < 0) {
16081604
dai_report_reload_xrun(dd[i], dev, 0);
16091605
return ret;
@@ -1629,10 +1625,10 @@ int dai_zephyr_multi_endpoint_copy(struct dai_data **dd, struct comp_dev *dev,
16291625

16301626
status = dai_dma_multi_endpoint_cb(dd[i], dev, frames, multi_endpoint_buffer);
16311627
if (status == SOF_DMA_CB_STATUS_END)
1632-
sof_dma_stop(dd[i]->chan->dma, dd[i]->chan->index);
1628+
sof_dma_stop(dd[i]->dma, dd[i]->chan_index);
16331629

16341630
copy_bytes = frames * audio_stream_frame_bytes(&dd[i]->dma_buffer->stream);
1635-
ret = sof_dma_reload(dd[i]->chan->dma, dd[i]->chan->index, copy_bytes);
1631+
ret = sof_dma_reload(dd[i]->dma, dd[i]->chan_index, copy_bytes);
16361632
if (ret < 0) {
16371633
dai_report_reload_xrun(dd[i], dev, copy_bytes);
16381634
return ret;
@@ -1821,7 +1817,7 @@ int dai_common_copy(struct dai_data *dd, struct comp_dev *dev, pcm_converter_fun
18211817
comp_warn(dev, "nothing to copy, src_frames: %u, sink_frames: %u",
18221818
src_frames, sink_frames);
18231819
#endif
1824-
sof_dma_reload(dd->chan->dma, dd->chan->index, 0);
1820+
sof_dma_reload(dd->dma, dd->chan_index, 0);
18251821
return 0;
18261822
}
18271823

@@ -1831,9 +1827,9 @@ int dai_common_copy(struct dai_data *dd, struct comp_dev *dev, pcm_converter_fun
18311827
comp_warn(dev, "dai trigger copy failed");
18321828

18331829
if (dai_dma_cb(dd, dev, copy_bytes, converter) == SOF_DMA_CB_STATUS_END)
1834-
sof_dma_stop(dd->chan->dma, dd->chan->index);
1830+
sof_dma_stop(dd->dma, dd->chan_index);
18351831

1836-
ret = sof_dma_reload(dd->chan->dma, dd->chan->index, copy_bytes);
1832+
ret = sof_dma_reload(dd->dma, dd->chan_index, copy_bytes);
18371833
if (ret < 0) {
18381834
dai_report_reload_xrun(dd, dev, copy_bytes);
18391835
return ret;
@@ -1871,7 +1867,7 @@ int dai_common_ts_config_op(struct dai_data *dd, struct comp_dev *dev)
18711867
struct dai_ts_cfg *cfg = &dd->ts_config;
18721868

18731869
comp_dbg(dev, "dai_ts_config()");
1874-
if (!dd->chan) {
1870+
if (dd->chan_index < 0) {
18751871
comp_err(dev, "No DMA channel information");
18761872
return -EINVAL;
18771873
}
@@ -1894,7 +1890,7 @@ int dai_common_ts_config_op(struct dai_data *dd, struct comp_dev *dev)
18941890
cfg->direction = dai->direction;
18951891
cfg->index = dd->dai->index;
18961892
cfg->dma_id = dd->dma->plat_data.id;
1897-
cfg->dma_chan_index = dd->chan->index;
1893+
cfg->dma_chan_index = dd->chan_index;
18981894
cfg->dma_chan_count = dd->dma->plat_data.channels;
18991895

19001896
return dai_ts_config(dd->dai->dev, cfg);

src/include/sof/lib/dai-zephyr.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -117,7 +117,7 @@ typedef int (*channel_copy_func)(const struct audio_stream *src, unsigned int sr
117117
*/
118118
struct dai_data {
119119
/* local DMA config */
120-
struct dma_chan_data *chan;
120+
int chan_index;
121121
uint32_t stream_id;
122122
struct dma_sg_config config;
123123
struct dma_config *z_config;

src/ipc/ipc3/dai.c

Lines changed: 15 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -209,7 +209,7 @@ int ipc_dai_data_config(struct dai_data *dd, struct comp_dev *dev)
209209
}
210210
pin_data->pin_num = dd->dai->index;
211211
pin_data->pin_dir = dai->direction;
212-
pin_data->dma_channel = dd->chan ? dd->chan->index : 0xFFFF;
212+
pin_data->dma_channel = dd->chan_index >= 0 ? dd->chan_index : 0xFFFF;
213213
pin_data->index = 0xFFFF;
214214
pin_data->instance = 0xFFFF;
215215
dev_data->dai_index_ptr = pin_data;
@@ -311,16 +311,16 @@ void dai_dma_release(struct dai_data *dd, struct comp_dev *dev)
311311
}
312312

313313
/* put the allocated DMA channel first */
314-
if (dd->chan) {
314+
if (dd->chan_index >= 0) {
315315
/* remove callback */
316-
notifier_unregister(dev, dd->chan, NOTIFIER_ID_DMA_COPY);
316+
notifier_unregister(dev, &dd->dma->chan[dd->chan_index],
317+
NOTIFIER_ID_DMA_COPY);
317318
#if CONFIG_ZEPHYR_NATIVE_DRIVERS
318-
dma_release_channel(dd->chan->dma->z_dev, dd->chan->index);
319+
dma_release_channel(dd->dma->z_dev, dd->chan_index);
319320
#else
320-
dma_channel_put_legacy(dd->chan);
321+
dma_channel_put_legacy(&dd->dma->chan[dd->chan_index]);
321322
#endif
322-
dd->chan->dev_data = NULL;
323-
dd->chan = NULL;
323+
dd->chan_index = -EINVAL;
324324
}
325325
}
326326

@@ -352,22 +352,22 @@ int dai_config(struct dai_data *dd, struct comp_dev *dev, struct ipc_config_dai
352352
if (SOF_DAI_QUIRK_IS_SET(config->flags, SOF_DAI_CONFIG_FLAGS_2_STEP_STOP))
353353
dd->delayed_dma_stop = true;
354354

355-
if (dd->chan) {
355+
if (dd->chan_index >= 0) {
356356
comp_info(dev, "Configured. dma channel index %d, ignore...",
357-
dd->chan->index);
357+
dd->chan_index);
358358
return 0;
359359
}
360360
break;
361361
case SOF_DAI_CONFIG_FLAGS_HW_FREE:
362-
if (!dd->chan)
362+
if (dd->chan_index < 0)
363363
return 0;
364364

365365
/* stop DMA and reset config for two-step stop DMA */
366366
if (dd->delayed_dma_stop) {
367367
#if CONFIG_ZEPHYR_NATIVE_DRIVERS
368-
ret = dma_stop(dd->chan->dma->z_dev, dd->chan->index);
368+
ret = dma_stop(dd->dma->z_dev, dd->chan_index);
369369
#else
370-
ret = dma_stop_delayed_legacy(dd->chan);
370+
ret = dma_stop_delayed_legacy(&dd->dma->chan[dd->chan_index]);
371371
#endif
372372
if (ret < 0)
373373
return ret;
@@ -377,12 +377,12 @@ int dai_config(struct dai_data *dd, struct comp_dev *dev, struct ipc_config_dai
377377

378378
return 0;
379379
case SOF_DAI_CONFIG_FLAGS_PAUSE:
380-
if (!dd->chan)
380+
if (dd->chan_index < 0)
381381
return 0;
382382
#if CONFIG_ZEPHYR_NATIVE_DRIVERS
383-
return dma_stop(dd->chan->dma->z_dev, dd->chan->index);
383+
return dma_stop(dd->dma->z_dev, dd->chan_index);
384384
#else
385-
return dma_stop_delayed_legacy(dd->chan);
385+
return dma_stop_delayed_legacy(&dd->dma->chan[dd->chan_index]);
386386
#endif
387387
default:
388388
break;

src/ipc/ipc4/dai.c

Lines changed: 8 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -216,7 +216,7 @@ void dai_dma_release(struct dai_data *dd, struct comp_dev *dev)
216216
}
217217

218218
/* put the allocated DMA channel first */
219-
if (dd->chan) {
219+
if (dd->chan_index >= 0) {
220220
struct ipc4_llp_reading_slot slot;
221221

222222
if (dd->slot_info.node_id) {
@@ -237,11 +237,10 @@ void dai_dma_release(struct dai_data *dd, struct comp_dev *dev)
237237
* TODO: refine power management when stream is paused
238238
*/
239239
/* if reset is after pause dma has already been stopped */
240-
dma_stop(dd->chan->dma->z_dev, dd->chan->index);
240+
dma_stop(dd->dma->z_dev, dd->chan_index);
241241

242-
dma_release_channel(dd->chan->dma->z_dev, dd->chan->index);
243-
dd->chan->dev_data = NULL;
244-
dd->chan = NULL;
242+
dma_release_channel(dd->dma->z_dev, dd->chan_index);
243+
dd->chan_index = -EINVAL;
245244
}
246245
}
247246

@@ -365,9 +364,9 @@ __cold int dai_config(struct dai_data *dd, struct comp_dev *dev,
365364
return 0;
366365
}
367366

368-
if (dd->chan) {
367+
if (dd->chan_index >= 0) {
369368
comp_info(dev, "Configured. dma channel index %d, ignore...",
370-
dd->chan->index);
369+
dd->chan_index);
371370
return 0;
372371
}
373372

@@ -425,7 +424,7 @@ int dai_common_position(struct dai_data *dd, struct comp_dev *dev,
425424
platform_dai_wallclock(dev, &dd->wallclock);
426425
posn->wallclock = dd->wallclock;
427426

428-
ret = dma_get_status(dd->dma->z_dev, dd->chan->index, &status);
427+
ret = dma_get_status(dd->dma->z_dev, dd->chan_index, &status);
429428
if (ret < 0)
430429
return ret;
431430

@@ -450,7 +449,7 @@ void dai_dma_position_update(struct dai_data *dd, struct comp_dev *dev)
450449
if (!dd->slot_info.node_id)
451450
return;
452451

453-
ret = dma_get_status(dd->dma->z_dev, dd->chan->index, &status);
452+
ret = dma_get_status(dd->dma->z_dev, dd->chan_index, &status);
454453
if (ret < 0)
455454
return;
456455

0 commit comments

Comments
 (0)