Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
66 changes: 31 additions & 35 deletions src/audio/dai-zephyr.c
Original file line number Diff line number Diff line change
Expand Up @@ -516,6 +516,7 @@ __cold int dai_common_new(struct dai_data *dd, struct comp_dev *dev,
dir = dai_cfg->direction == SOF_IPC_STREAM_PLAYBACK ?
SOF_DMA_DIR_MEM_TO_DEV : SOF_DMA_DIR_DEV_TO_MEM;

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

dma_sg_init(&dd->config.elem_array);
Comment thread
kv2019i marked this conversation as resolved.
dd->xrun = 0;
dd->chan = NULL;

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

if (dd->chan) {
sof_dma_release_channel(dd->dma, dd->chan->index);
dd->chan->dev_data = NULL;
if (dd->chan_index >= 0) {
sof_dma_release_channel(dd->dma, dd->chan_index);
dd->chan_index = -EINVAL;
}

sof_dma_put(dd->dma);
Expand Down Expand Up @@ -1160,9 +1160,9 @@ int dai_common_config_prepare(struct dai_data *dd, struct comp_dev *dev)
return -EINVAL;
}

if (dd->chan) {
if (dd->chan_index >= 0) {
comp_info(dev, "dma channel index %d already configured",
dd->chan->index);
dd->chan_index);
return 0;
}

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

/* get DMA channel */
channel = sof_dma_request_channel(dd->dma, channel);
if (channel < 0) {
comp_err(dev, "dma_request_channel() failed");
dd->chan = NULL;
return -EIO;
dd->chan_index = sof_dma_request_channel(dd->dma, channel);
if (dd->chan_index < 0) {
comp_err(dev, "dma_request_channel() failed ch %d ret %d", channel, dd->chan_index);
return dd->chan_index;
}
Comment thread
kv2019i marked this conversation as resolved.

dd->chan = &dd->dma->chan[channel];
dd->chan->dev_data = dd;

comp_dbg(dev, "new configured dma channel index %d",
dd->chan->index);
dd->chan_index);

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

dd->total_data_processed = 0;

if (!dd->chan) {
comp_err(dev, "Missing dd->chan.");
if (dd->chan_index < 0) {
comp_err(dev, "Missing dd->chan_index.");
comp_set_state(dev, COMP_TRIGGER_RESET);
return -EINVAL;
}
Expand All @@ -1220,7 +1216,7 @@ int dai_common_prepare(struct dai_data *dd, struct comp_dev *dev)
return 0;
}

ret = sof_dma_config(dd->chan->dma, dd->chan->index, dd->z_config);
ret = sof_dma_config(dd->dma, dd->chan_index, dd->z_config);
if (ret < 0)
comp_set_state(dev, COMP_TRIGGER_RESET);

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

/* only start the DAI if we are not XRUN handling */
if (dd->xrun == 0) {
ret = sof_dma_start(dd->chan->dma, dd->chan->index);
ret = sof_dma_start(dd->dma, dd->chan_index);
if (ret < 0)
return ret;

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

/* dma_config needed after stop */
ret = sof_dma_config(dd->chan->dma, dd->chan->index, dd->z_config);
ret = sof_dma_config(dd->dma, dd->chan_index, dd->z_config);
if (ret < 0)
return ret;

ret = sof_dma_start(dd->chan->dma, dd->chan->index);
ret = sof_dma_start(dd->dma, dd->chan_index);
if (ret < 0)
return ret;

Expand Down Expand Up @@ -1382,11 +1378,11 @@ static int dai_comp_trigger_internal(struct dai_data *dd, struct comp_dev *dev,
* as soon as possible.
*/
#if CONFIG_COMP_DAI_STOP_TRIGGER_ORDER_REVERSE
ret = sof_dma_stop(dd->chan->dma, dd->chan->index);
ret = sof_dma_stop(dd->dma, dd->chan_index);
dai_trigger_op(dd->dai, cmd, dev->direction);
#else
dai_trigger_op(dd->dai, cmd, dev->direction);
ret = sof_dma_stop(dd->chan->dma, dd->chan->index);
ret = sof_dma_stop(dd->dma, dd->chan_index);
if (ret) {
comp_warn(dev, "dma was stopped earlier");
ret = 0;
Expand All @@ -1396,11 +1392,11 @@ static int dai_comp_trigger_internal(struct dai_data *dd, struct comp_dev *dev,
case COMP_TRIGGER_PAUSE:
comp_dbg(dev, "PAUSE");
#if CONFIG_COMP_DAI_STOP_TRIGGER_ORDER_REVERSE
ret = sof_dma_suspend(dd->chan->dma, dd->chan->index);
ret = sof_dma_suspend(dd->dma, dd->chan_index);
dai_trigger_op(dd->dai, cmd, dev->direction);
#else
dai_trigger_op(dd->dai, cmd, dev->direction);
ret = sof_dma_suspend(dd->chan->dma, dd->chan->index);
ret = sof_dma_suspend(dd->dma, dd->chan_index);
#endif
break;
case COMP_TRIGGER_PRE_START:
Expand Down Expand Up @@ -1498,7 +1494,7 @@ static int dai_comp_trigger(struct comp_dev *dev, int cmd)
*/
static int dai_get_status(struct comp_dev *dev, struct dai_data *dd, struct dma_status *stat)
{
int ret = sof_dma_get_status(dd->chan->dma, dd->chan->index, stat);
int ret = sof_dma_get_status(dd->dma, dd->chan_index, stat);
#if CONFIG_XRUN_NOTIFICATIONS_ENABLE
if (ret == -EPIPE && !dd->xrun_notification_sent) {
dd->xrun_notification_sent = send_copier_gateway_xrun_notif_msg
Expand Down Expand Up @@ -1603,7 +1599,7 @@ int dai_zephyr_multi_endpoint_copy(struct dai_data **dd, struct comp_dev *dev,
#endif

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

status = dai_dma_multi_endpoint_cb(dd[i], dev, frames, multi_endpoint_buffer);
if (status == SOF_DMA_CB_STATUS_END)
sof_dma_stop(dd[i]->chan->dma, dd[i]->chan->index);
sof_dma_stop(dd[i]->dma, dd[i]->chan_index);

copy_bytes = frames * audio_stream_frame_bytes(&dd[i]->dma_buffer->stream);
ret = sof_dma_reload(dd[i]->chan->dma, dd[i]->chan->index, copy_bytes);
ret = sof_dma_reload(dd[i]->dma, dd[i]->chan_index, copy_bytes);
if (ret < 0) {
dai_report_reload_xrun(dd[i], dev, copy_bytes);
return ret;
Expand Down Expand Up @@ -1821,7 +1817,7 @@ int dai_common_copy(struct dai_data *dd, struct comp_dev *dev, pcm_converter_fun
comp_warn(dev, "nothing to copy, src_frames: %u, sink_frames: %u",
src_frames, sink_frames);
#endif
sof_dma_reload(dd->chan->dma, dd->chan->index, 0);
sof_dma_reload(dd->dma, dd->chan_index, 0);
return 0;
}

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

if (dai_dma_cb(dd, dev, copy_bytes, converter) == SOF_DMA_CB_STATUS_END)
sof_dma_stop(dd->chan->dma, dd->chan->index);
sof_dma_stop(dd->dma, dd->chan_index);

ret = sof_dma_reload(dd->chan->dma, dd->chan->index, copy_bytes);
ret = sof_dma_reload(dd->dma, dd->chan_index, copy_bytes);
if (ret < 0) {
dai_report_reload_xrun(dd, dev, copy_bytes);
return ret;
Expand Down Expand Up @@ -1871,7 +1867,7 @@ int dai_common_ts_config_op(struct dai_data *dd, struct comp_dev *dev)
struct dai_ts_cfg *cfg = &dd->ts_config;

comp_dbg(dev, "dai_ts_config()");
if (!dd->chan) {
if (dd->chan_index < 0) {
comp_err(dev, "No DMA channel information");
return -EINVAL;
}
Expand All @@ -1894,7 +1890,7 @@ int dai_common_ts_config_op(struct dai_data *dd, struct comp_dev *dev)
cfg->direction = dai->direction;
cfg->index = dd->dai->index;
cfg->dma_id = dd->dma->plat_data.id;
cfg->dma_chan_index = dd->chan->index;
cfg->dma_chan_index = dd->chan_index;
cfg->dma_chan_count = dd->dma->plat_data.channels;

return dai_ts_config(dd->dai->dev, cfg);
Expand Down
6 changes: 3 additions & 3 deletions src/audio/host-zephyr.c
Original file line number Diff line number Diff line change
Expand Up @@ -651,7 +651,7 @@ int host_common_trigger(struct host_data *hd, struct comp_dev *dev, int cmd)
if (cmd != COMP_TRIGGER_START && hd->copy_type == COMP_COPY_ONE_SHOT)
return ret;

if (hd->chan_index == -EINVAL) {
if (hd->chan_index < 0) {
comp_err(dev, "no dma channel configured");
return -EINVAL;
}
Expand Down Expand Up @@ -785,7 +785,7 @@ __cold void host_common_free(struct host_data *hd)
#endif

/* release DMA channel if not already done by reset */
if (hd->chan_index != -EINVAL) {
if (hd->chan_index >= 0) {
sof_dma_stop(hd->dma, hd->chan_index);
sof_dma_release_channel(hd->dma, hd->chan_index);
hd->chan_index = -EINVAL;
Expand Down Expand Up @@ -1171,7 +1171,7 @@ static int host_position(struct comp_dev *dev,

void host_common_reset(struct host_data *hd, uint16_t state)
{
if (hd->chan_index != -EINVAL) {
if (hd->chan_index >= 0) {
sof_dma_stop(hd->dma, hd->chan_index);
sof_dma_release_channel(hd->dma, hd->chan_index);
hd->chan_index = -EINVAL;
Expand Down
2 changes: 1 addition & 1 deletion src/include/sof/lib/dai-zephyr.h
Original file line number Diff line number Diff line change
Expand Up @@ -117,7 +117,7 @@ typedef int (*channel_copy_func)(const struct audio_stream *src, unsigned int sr
*/
struct dai_data {
/* local DMA config */
struct dma_chan_data *chan;
int chan_index;
uint32_t stream_id;
struct dma_sg_config config;
struct dma_config *z_config;
Expand Down
1 change: 1 addition & 0 deletions src/ipc/Kconfig
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ config IPC_MAJOR_3

config IPC_MAJOR_4
bool "IPC Major Version 4"
depends on ZEPHYR_NATIVE_DRIVERS || LIBRARY
help
This is an IPC version used by certain middleware on some IOT
Intel devices. Not for general use.
Expand Down
43 changes: 34 additions & 9 deletions src/ipc/ipc3/dai.c
Original file line number Diff line number Diff line change
Expand Up @@ -209,7 +209,11 @@ int ipc_dai_data_config(struct dai_data *dd, struct comp_dev *dev)
}
pin_data->pin_num = dd->dai->index;
pin_data->pin_dir = dai->direction;
#ifdef CONFIG_ZEPHYR_NATIVE_DRIVERS
pin_data->dma_channel = dd->chan_index >= 0 ? dd->chan_index : 0xFFFF;
#else
pin_data->dma_channel = dd->chan ? dd->chan->index : 0xFFFF;
#endif
pin_data->index = 0xFFFF;
pin_data->instance = 0xFFFF;
dev_data->dai_index_ptr = pin_data;
Expand Down Expand Up @@ -311,17 +315,23 @@ void dai_dma_release(struct dai_data *dd, struct comp_dev *dev)
}

/* put the allocated DMA channel first */
#ifdef CONFIG_ZEPHYR_NATIVE_DRIVERS
if (dd->chan_index >= 0) {
/* remove callback */
notifier_unregister(dev, &dd->dma->chan[dd->chan_index],
NOTIFIER_ID_DMA_COPY);
dma_release_channel(dd->dma->z_dev, dd->chan_index);
dd->chan_index = -EINVAL;
}
#else
if (dd->chan) {
/* remove callback */
notifier_unregister(dev, dd->chan, NOTIFIER_ID_DMA_COPY);
#if CONFIG_ZEPHYR_NATIVE_DRIVERS
dma_release_channel(dd->chan->dma->z_dev, dd->chan->index);
#else
dma_channel_put_legacy(dd->chan);
#endif
dd->chan->dev_data = NULL;
dd->chan = NULL;
}
#endif
}

int dai_config(struct dai_data *dd, struct comp_dev *dev, struct ipc_config_dai *common_config,
Expand Down Expand Up @@ -352,20 +362,33 @@ int dai_config(struct dai_data *dd, struct comp_dev *dev, struct ipc_config_dai
if (SOF_DAI_QUIRK_IS_SET(config->flags, SOF_DAI_CONFIG_FLAGS_2_STEP_STOP))
dd->delayed_dma_stop = true;

#ifdef CONFIG_ZEPHYR_NATIVE_DRIVERS
if (dd->chan_index >= 0) {
comp_info(dev, "Configured. dma channel index %d, ignore...",
dd->chan_index);
return 0;
}
#else
if (dd->chan) {
comp_info(dev, "Configured. dma channel index %d, ignore...",
dd->chan->index);
return 0;
}
#endif
break;
case SOF_DAI_CONFIG_FLAGS_HW_FREE:
#ifdef CONFIG_ZEPHYR_NATIVE_DRIVERS
if (dd->chan_index < 0)
return 0;
#else
if (!dd->chan)
return 0;
#endif

/* stop DMA and reset config for two-step stop DMA */
if (dd->delayed_dma_stop) {
#if CONFIG_ZEPHYR_NATIVE_DRIVERS
ret = dma_stop(dd->chan->dma->z_dev, dd->chan->index);
#ifdef CONFIG_ZEPHYR_NATIVE_DRIVERS
ret = dma_stop(dd->dma->z_dev, dd->chan_index);
#else
ret = dma_stop_delayed_legacy(dd->chan);
#endif
Expand All @@ -377,11 +400,13 @@ int dai_config(struct dai_data *dd, struct comp_dev *dev, struct ipc_config_dai

return 0;
case SOF_DAI_CONFIG_FLAGS_PAUSE:
if (!dd->chan)
#ifdef CONFIG_ZEPHYR_NATIVE_DRIVERS
if (dd->chan_index < 0)
return 0;
#if CONFIG_ZEPHYR_NATIVE_DRIVERS
return dma_stop(dd->chan->dma->z_dev, dd->chan->index);
return dma_stop(dd->dma->z_dev, dd->chan_index);
#else
if (!dd->chan)
return 0;
return dma_stop_delayed_legacy(dd->chan);
#endif
default:
Expand Down
7 changes: 6 additions & 1 deletion src/ipc/ipc4/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -2,14 +2,19 @@

# Files common to Zephyr and XTOS
add_local_sources(sof
dai.c
handler-user.c
handler-kernel.c
helper.c
logging.c
notification.c
)

# The DAI interface is not implemented in library builds and
# code depends on Zephyr DAI driver definitions to be available.
if(NOT CONFIG_LIBRARY)
add_local_sources(sof dai.c)
endif()

is_zephyr(zephyr)
if(zephyr) ### Zephyr ###

Expand Down
Loading
Loading