Skip to content
Closed
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
1 change: 1 addition & 0 deletions app/boards/intel_adsp_ace15_mtpm.conf
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,7 @@ CONFIG_LOG=y
CONFIG_LOG_MODE_DEFERRED=y
CONFIG_LOG_FUNC_NAME_PREFIX_INF=y
CONFIG_COMP_VOLUME_WINDOWS_FADE=y
CONFIG_COMP_UP_DOWN_MIXER=y
CONFIG_SYS_CLOCK_TICKS_PER_SEC=12000
CONFIG_SYS_CLOCK_HW_CYCLES_PER_SEC=38400000

Expand Down
3 changes: 2 additions & 1 deletion src/audio/dai-zephyr.c
Original file line number Diff line number Diff line change
Expand Up @@ -934,6 +934,7 @@ static int dai_reset(struct comp_dev *dev)
dai_dma_release(dev);

dma_sg_free(&config->elem_array);
rfree(dd->z_config->head_block);
rfree(dd->z_config);

if (dd->dma_buffer) {
Expand Down Expand Up @@ -1234,7 +1235,7 @@ static int dai_copy(struct comp_dev *dev)
return ret;
}

dai_dma_position_update(dev);
//dai_dma_position_update(dev);

return ret;
}
Expand Down
1 change: 1 addition & 0 deletions src/audio/pipeline/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -6,4 +6,5 @@ add_local_sources(sof
pipeline-params.c
pipeline-xrun.c
pipeline-schedule.c
chain_dma.c
)
80 changes: 80 additions & 0 deletions src/audio/pipeline/chain_dma.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,80 @@
#include <sof/audio/chain_dma.h>
#include <ipc4/error_status.h>
#include <ipc4/module.h>

/* 6a0a274f-27cc-4afb-a3e7-3444723f432e */
DECLARE_SOF_RT_UUID("chain_dma", chain_dma_uuid, 0x6a0a274f, 0x27cc, 0x4afb,
0xa3, 0xe7, 0x34, 0x44, 0x72, 0x3f, 0x43, 0x2e);
DECLARE_TR_CTX(chain_dma_tr, SOF_UUID(chain_dma_uuid), LOG_LEVEL_INFO);

int chain_dma_start(struct comp_dev *dev, uint8_t host_dma_id)
{
return IPC4_SUCCESS;
}

int chain_dma_pause(struct comp_dev *dev, uint8_t host_dma_id)
{
return IPC4_SUCCESS;
}

int chain_dma_trigger(struct comp_dev *dev, int cmd)
{
switch (cmd) {
case COMP_TRIGGER_START:
chain_dma_start(dev, cmd);
break;
case COMP_TRIGGER_PAUSE:
chain_dma_pause(dev, cmd);
break;
default:
return 0;
}
return IPC4_SUCCESS;
}

int chain_dma_remove(struct comp_dev *dev, uint8_t host_dma_id)
{
return IPC4_SUCCESS;
}

int chain_dma_create(const struct comp_driver *drv, uint8_t host_dma_id, uint8_t link_dma_id, uint32_t fifo_size, bool scs)
{
struct comp_dev *dev;

dev = comp_alloc(drv, sizeof(*dev));
if (!dev)
return IPC4_INVALID_REQUEST;

int comp_id = IPC4_COMP_ID(host_dma_id + IPC4_MAX_MODULE_COUNT,
link_dma_id);

struct chain_dma_data *cd = comp_get_drvdata(dev);
size_t size = sizeof(*cd);
cd = rzalloc(SOF_MEM_ZONE_RUNTIME, 0, SOF_MEM_CAPS_RAM, size);
return IPC4_SUCCESS;
}



static const struct comp_driver comp_chain_dma = {
.type = SOF_COMP_CHAIN_DMA,
.uid = SOF_RT_UUID(chain_dma_uuid),
.tctx = &chain_dma_tr,
.ops = {
.chain_dma_create = chain_dma_create,
.trigger = chain_dma_trigger,
.free = chain_dma_remove,
},
};

static SHARED_DATA struct comp_driver_info comp_chain_dma_info = {
.drv = &comp_chain_dma,
};

static void sys_comp_chain_dma_init(void)
{
comp_register(platform_shared_get(&comp_chain_dma_info,
sizeof(comp_chain_dma_info)));
}

DECLARE_MODULE(sys_comp_chain_dma_init);
10 changes: 4 additions & 6 deletions src/audio/src/src.c
Original file line number Diff line number Diff line change
Expand Up @@ -946,16 +946,14 @@ static int src_check_buffer_sizes(struct comp_data *cd,

n = audio_stream_frame_bytes(source_stream) * (blk_in + cd->source_frames);
if (source_stream->size < n) {
comp_cl_err(&comp_src, "Source size %d is less than required %d",
source_stream->size, n);
return -ENOBUFS;
comp_cl_warn(&comp_src, "Source size %d is less than required %d",
source_stream->size, n);
}

n = audio_stream_frame_bytes(sink_stream) * (blk_out + cd->sink_frames);
if (sink_stream->size < n) {
comp_cl_err(&comp_src, "Sink size %d is less than required %d",
sink_stream->size, n);
return -ENOBUFS;
comp_cl_warn(&comp_src, "Sink size %d is less than required %d",
sink_stream->size, n);
}

return 0;
Expand Down
5 changes: 3 additions & 2 deletions src/audio/up_down_mixer/up_down_mixer.c
Original file line number Diff line number Diff line change
Expand Up @@ -337,9 +337,10 @@ static void up_down_mixer_free(struct comp_dev *dev)
rfree(dev);
}

static int init_up_down_mixer(struct comp_dev *dev, struct comp_ipc_config *config, void *spec)
static int init_up_down_mixer(struct comp_dev *dev, const struct comp_ipc_config *config,
const void *spec)
{
struct ipc4_up_down_mixer_module_cfg *up_down_mixer = spec;
const struct ipc4_up_down_mixer_module_cfg *up_down_mixer = spec;
struct up_down_mixer_data *cd;
int ret;

Expand Down
1 change: 1 addition & 0 deletions src/include/ipc/topology.h
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@ enum sof_comp_type {
SOF_COMP_NONE = 0,
SOF_COMP_HOST,
SOF_COMP_DAI,
SOF_COMP_CHAIN_DMA,
SOF_COMP_SG_HOST, /**< scatter gather variant */
SOF_COMP_SG_DAI, /**< scatter gather variant */
SOF_COMP_VOLUME,
Expand Down
3 changes: 3 additions & 0 deletions src/include/ipc4/error_status.h
Original file line number Diff line number Diff line change
Expand Up @@ -124,6 +124,9 @@ enum ipc4_status {
/**< Reverted for ULP purposes */
IPC4_PIPELINE_STATE_NOT_SET = 164,

/**< HDA chained gateways wrong state transition*/
IPC4_INVALID_CHAIN_STATE_TRANSITION = 3018,

IPC4_MAX_STATUS = ((1 << IPC4_IXC_STATUS_BITS) - 1)
};
#endif
35 changes: 35 additions & 0 deletions src/include/sof/audio/chain_dma.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
#include <sof/audio/buffer.h>
#include <sof/audio/component.h>
#include <sof/audio/component_ext.h>
#include <sof/audio/pipeline.h>
#include <sof/common.h>
#include <sof/ipc/topology.h>
#include <sof/ipc/common.h>
#include <ipc/dai.h>

static const uint32_t MAX_CHAIN_NUMBER = DAI_NUM_HDA_OUT + DAI_NUM_HDA_IN;

/* chain dma component private data */
struct chain_dma_data {
bool first_data_received_;
//! Node id of host HD/A DMA
uint32_t output_node_id_;
//! Node id of link HD/A DMA
uint32_t input_node_id_;
uint32_t* hw_buffer_;
bool under_over_run_notification_sent_;
};

int chain_dma_create(const struct comp_driver *drv, uint8_t host_dma_id, uint8_t link_dma_id, uint32_t fifo_size, bool scs);

int chain_dma_start(struct comp_dev *dev, uint8_t host_dma_id);

int chain_dma_pause(struct comp_dev *dev, uint8_t host_dma_id);

int chain_dma_remove(struct comp_dev *dev, uint8_t host_dma_id);

int chain_dma_trigger(struct comp_dev *dev, int cmd);

void SetReadPointer(uint32_t read_pointer);

void SetWritePointer(uint32_t write_pointer);
4 changes: 4 additions & 0 deletions src/include/sof/audio/component.h
Original file line number Diff line number Diff line change
Expand Up @@ -307,6 +307,10 @@ struct comp_ops {
const struct comp_ipc_config *ipc_config,
const void *ipc_specific_config);

struct comp_dev *(*chain_dma_create)(const struct comp_driver *drv,
uint8_t host_dma_id, uint8_t link_dma_id,
uint32_t fifo_size, bool scs);

/**
* Called to delete the specified component device.
* @param dev Component device to be deleted.
Expand Down
1 change: 1 addition & 0 deletions src/include/sof/ipc/topology.h
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,7 @@ const struct comp_driver *ipc4_get_comp_drv(int module_id);
struct comp_dev *ipc4_get_comp_dev(uint32_t comp_id);
int ipc4_add_comp_dev(struct comp_dev *dev);
const struct comp_driver *ipc4_get_drv(uint8_t *uuid);
int ipc4_create_io_driver_for_chain(struct ipc4_chain_dma *cdma);
int ipc4_create_chain_dma(struct ipc *ipc, struct ipc4_chain_dma *cdma);
int ipc4_trigger_chain_dma(struct ipc *ipc, struct ipc4_chain_dma *cdma);
#else
Expand Down
112 changes: 89 additions & 23 deletions src/ipc/ipc4/handler.c
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@
#include <sof/audio/buffer.h>
#include <sof/audio/component_ext.h>
#include <sof/audio/pipeline.h>
#include <sof/audio/chain_dma.h>
#include <sof/common.h>
#include <sof/ipc/topology.h>
#include <sof/ipc/common.h>
Expand Down Expand Up @@ -458,36 +459,101 @@ static int ipc4_load_library(struct ipc4_message_request *ipc4)
}
#endif

#include "sof/mem_win_debug.h"
static int ipc4_process_chain_dma(struct ipc4_message_request *ipc4)
{
struct sof_uuid uuid = {0x6a0a274f, 0x27cc, 0x4afb, {0xa3, 0xe7, 0x34,
0x44, 0x72, 0x3f, 0x43, 0x2e}};
struct ipc4_chain_dma cdma;
struct ipc *ipc = ipc_get();
int ret;
int ret = IPC4_INVALID_REQUEST;

memcpy_s(&cdma, sizeof(cdma), ipc4, sizeof(cdma));

if (cdma.primary.r.allocate && cdma.extension.r.fifo_size) {
ret = ipc4_create_chain_dma(ipc, &cdma);
if (ret) {
tr_err(&ipc_tr, "failed to create chain dma %d", ret);
return ret;
}

/* if enable is not set, chain dma pipeline is not going to be triggered */
if (!cdma.primary.r.enable)
return ret;
}

atomic_set(&msg_data.delayed_reply, 1);
ret = ipc4_trigger_chain_dma(ipc, &cdma);
/* it is not scheduled in another thread */
if (ret != PPL_STATUS_SCHEDULED) {
atomic_set(&msg_data.delayed_reply, 0);
msg_data.delayed_error = 0;
} else {
ret = 0;
}

const uint8_t link_dma_id = cdma.primary.r.link_dma_id;
const uint8_t host_dma_id = cdma.primary.r.host_dma_id;

const uint32_t fifo_size = cdma.extension.r.fifo_size;
const bool allocate = cdma.primary.r.allocate;
const bool enable = cdma.primary.r.enable;
const bool scs = cdma.primary.r.scs;

MEM_WIN_DEBUG0(0xaaa0,0,0,0);
int comp_id = IPC4_COMP_ID(host_dma_id + IPC4_MAX_MODULE_COUNT,
link_dma_id);

if (allocate)
{
ret = ipc4_create_io_driver_for_chain(&cdma);
struct ipc_comp_dev* cdma_comp = ipc_get_comp_by_id(ipc, comp_id);
MEM_WIN_DEBUG0(0xaab0,cdma_comp,0,0);
assert(cdma_comp != NULL);
if(ret == IPC4_SUCCESS || ret == IPC4_INVALID_CHAIN_STATE_TRANSITION)
{
// valid ret code.
}
else
{
return IPC4_INVALID_REQUEST;
}
const struct comp_driver *drv;
drv = ipc4_get_drv((uint8_t *)&uuid);
MEM_WIN_DEBUG0(0xaab1,drv,0,0);
assert(drv != NULL);
if (enable)
{
drv->ops.trigger(cdma_comp->cd, COMP_TRIGGER_START);
}
else
{
drv->ops.trigger(cdma_comp->cd, COMP_TRIGGER_PAUSE);
}
MEM_WIN_DEBUG0(0xaab2,drv,0,0);
}
else
{
const struct comp_driver *drv;
drv = ipc4_get_drv((uint8_t *)&uuid);
struct ipc_comp_dev* cdma_comp = ipc_get_comp_by_id(ipc, comp_id);
if (enable)
{
return IPC4_INVALID_REQUEST;
}
else
{
//ret = chain_dma_mgr->PauseChain(host_dma_id);
drv->ops.trigger(cdma_comp->cd, COMP_TRIGGER_PAUSE);
}
if (ret == IPC4_SUCCESS)
{
//ret = chain_dma_mgr->RemoveChain(host_dma_id);
drv->ops.free(cdma_comp->cd);
}
}

//PREVIOUS IMPLEMENTATION
// if (cdma.primary.r.allocate && cdma.extension.r.fifo_size) {
// ret = ipc4_create_chain_dma(ipc, &cdma);
// if (ret) {
// tr_err(&ipc_tr, "failed to create chain dma %d", ret);
// return ret;
// }

// /* if enable is not set, chain dma pipeline is not going to be triggered */
// if (!cdma.primary.r.enable)
// return ret;
// }

// atomic_set(&msg_data.delayed_reply, 1);
// ret = ipc4_trigger_chain_dma(ipc, &cdma);
// /* it is not scheduled in another thread */
// if (ret != PPL_STATUS_SCHEDULED) {
// atomic_set(&msg_data.delayed_reply, 0);
// msg_data.delayed_error = 0;
// } else {
// ret = 0;
// }
MEM_WIN_DEBUG0(0xaaa1,0,0,0);
return ret;
}

Expand Down
Loading