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
help
This is an IPC version used by certain middleware on some IOT
Intel devices. Not for general use.
Expand Down
78 changes: 8 additions & 70 deletions src/ipc/ipc4/dai.c
Original file line number Diff line number Diff line change
Expand Up @@ -143,9 +143,7 @@ int ipc_dai_data_config(struct dai_data *dd, struct comp_dev *dev)
{
struct ipc_config_dai *dai = &dd->ipc_config;
struct ipc4_copier_module_cfg *copier_cfg = dd->dai_spec_config;
#ifdef CONFIG_ZEPHYR_NATIVE_DRIVERS
struct dai *dai_p = dd->dai;
#endif

if (!dai) {
comp_err(dev, "no dai!\n");
Expand Down Expand Up @@ -174,12 +172,7 @@ int ipc_dai_data_config(struct dai_data *dd, struct comp_dev *dev)
case SOF_DAI_INTEL_HDA:
break;
case SOF_DAI_INTEL_ALH:
#ifdef CONFIG_ZEPHYR_NATIVE_DRIVERS
dd->stream_id = dai_get_stream_id(dai_p, dai->direction);
#else
/* only native Zephyr driver supported */
return -EINVAL;
#endif
/* SDW HW FIFO always requires 32bit MSB aligned sample data for
* all formats, such as 8/16/24/32 bits.
*/
Expand Down Expand Up @@ -223,7 +216,7 @@ void dai_dma_release(struct dai_data *dd, struct comp_dev *dev)
}

/* put the allocated DMA channel first */
if (dd->chan) {
if (dd->chan_index >= 0) {
struct ipc4_llp_reading_slot slot;
Comment thread
kv2019i marked this conversation as resolved.

if (dd->slot_info.node_id) {
Expand All @@ -243,17 +236,11 @@ void dai_dma_release(struct dai_data *dd, struct comp_dev *dev)
* pause to stop.
* TODO: refine power management when stream is paused
*/
#if CONFIG_ZEPHYR_NATIVE_DRIVERS
/* if reset is after pause dma has already been stopped */
dma_stop(dd->chan->dma->z_dev, dd->chan->index);
dma_stop(dd->dma->z_dev, dd->chan_index);

dma_release_channel(dd->chan->dma->z_dev, dd->chan->index);
#else
dma_stop_legacy(dd->chan);
dma_channel_put_legacy(dd->chan);
#endif
dd->chan->dev_data = NULL;
dd->chan = NULL;
dma_release_channel(dd->dma->z_dev, dd->chan_index);
dd->chan_index = -EINVAL;
}
}

Expand Down Expand Up @@ -377,9 +364,9 @@ __cold int dai_config(struct dai_data *dd, struct comp_dev *dev,
return 0;
}

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

Expand Down Expand Up @@ -425,7 +412,6 @@ __cold int dai_config(struct dai_data *dd, struct comp_dev *dev,
copier_cfg->gtw_cfg.config_data, size);
}

#if CONFIG_ZEPHYR_NATIVE_DRIVERS
int dai_common_position(struct dai_data *dd, struct comp_dev *dev,
struct sof_ipc_stream_posn *posn)
{
Expand All @@ -438,7 +424,7 @@ int dai_common_position(struct dai_data *dd, struct comp_dev *dev,
platform_dai_wallclock(dev, &dd->wallclock);
posn->wallclock = dd->wallclock;

ret = dma_get_status(dd->dma->z_dev, dd->chan->index, &status);
ret = dma_get_status(dd->dma->z_dev, dd->chan_index, &status);
if (ret < 0)
return ret;

Expand All @@ -463,7 +449,7 @@ void dai_dma_position_update(struct dai_data *dd, struct comp_dev *dev)
if (!dd->slot_info.node_id)
return;

ret = dma_get_status(dd->dma->z_dev, dd->chan->index, &status);
ret = dma_get_status(dd->dma->z_dev, dd->chan_index, &status);
if (ret < 0)
return;

Expand All @@ -477,51 +463,3 @@ void dai_dma_position_update(struct dai_data *dd, struct comp_dev *dev)

mailbox_sw_regs_write(dd->slot_info.reg_offset, &slot, sizeof(slot));
}
#else
int dai_common_position(struct dai_data *dd, struct comp_dev *dev,
struct sof_ipc_stream_posn *posn)
{
struct dma_chan_status status;

/* total processed bytes count */
posn->dai_posn = dd->total_data_processed;

platform_dai_wallclock(dev, &dd->wallclock);
posn->wallclock = dd->wallclock;

status.ipc_posn_data = &posn->comp_posn;
dma_status_legacy(dd->chan, &status, dev->direction);

return 0;
}

int dai_position(struct comp_dev *dev, struct sof_ipc_stream_posn *posn)
{
struct dai_data *dd = comp_get_drvdata(dev);

return dai_common_position(dd, dev, posn);
}

void dai_dma_position_update(struct dai_data *dd, struct comp_dev *dev)
{
struct ipc4_llp_reading_slot slot;
struct dma_chan_status status;
uint32_t llp_data[2];

if (!dd->slot_info.node_id)
return;

status.ipc_posn_data = llp_data;
dma_status_legacy(dd->chan, &status, dev->direction);

platform_dai_wallclock(dev, &dd->wallclock);

slot.node_id = dd->slot_info.node_id;
slot.reading.llp_l = llp_data[0];
slot.reading.llp_u = llp_data[1];
slot.reading.wclk_l = (uint32_t)dd->wallclock;
slot.reading.wclk_u = (uint32_t)(dd->wallclock >> 32);

mailbox_sw_regs_write(dd->slot_info.reg_offset, &slot, sizeof(slot));
}
#endif
Loading