Skip to content
Merged
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
5 changes: 3 additions & 2 deletions src/drivers/intel/cavs/ipc.c
Original file line number Diff line number Diff line change
Expand Up @@ -200,9 +200,10 @@ enum task_state ipc_platform_do_cmd(void *data)

void ipc_platform_complete_cmd(void *data)
{
#if CONFIG_SUECREEK
struct ipc *ipc = data;
#endif

if (!cpu_is_me(ipc->core))
return;

/* write 1 to clear busy, and trigger interrupt to host*/
#if CAVS_VERSION == CAVS_VERSION_1_5
Expand Down
7 changes: 5 additions & 2 deletions src/idc/idc.c
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
#include <sof/audio/component.h>
#include <sof/audio/component_ext.h>
#include <sof/drivers/idc.h>
#include <sof/ipc/driver.h>
#include <sof/ipc/msg.h>
#include <sof/ipc/topology.h>
#include <sof/ipc/schedule.h>
Expand Down Expand Up @@ -120,9 +121,11 @@ int idc_wait_in_blocking_mode(uint32_t target_core, bool (*cond)(int))
static void idc_ipc(void)
{
struct ipc *ipc = ipc_get();
ipc_cmd_hdr *hdr = ipc->comp_data;

ipc_cmd(hdr);
ipc_cmd(ipc->comp_data);

/* Signal the host */
ipc_platform_complete_cmd(ipc);
}

/**
Expand Down
4 changes: 3 additions & 1 deletion src/include/sof/ipc/common.h
Original file line number Diff line number Diff line change
Expand Up @@ -68,6 +68,7 @@ struct ipc {

struct list_item msg_list; /* queue of messages to be sent */
bool is_notification_pending; /* notification is being sent to host */
unsigned int core; /* core, processing the IPC */

struct list_item comp_list; /* list of component devices */

Expand Down Expand Up @@ -190,8 +191,9 @@ void ipc_cmd(ipc_cmd_hdr *hdr);
/**
* \brief IPC message to be processed on other core.
* @param[in] core Core id for IPC to be processed on.
* @param[in] blocking Process in blocking mode: wait for completion.
* @return 1 if successful (reply sent by other core), error code otherwise.
*/
int ipc_process_on_core(uint32_t core);
int ipc_process_on_core(uint32_t core, bool blocking);

#endif /* __SOF_DRIVERS_IPC_H__ */
16 changes: 14 additions & 2 deletions src/ipc/ipc-common.c
Original file line number Diff line number Diff line change
Expand Up @@ -38,8 +38,9 @@ DECLARE_SOF_UUID("ipc", ipc_uuid, 0xbe60f97d, 0x78df, 0x4796,

DECLARE_TR_CTX(ipc_tr, SOF_UUID(ipc_uuid), LOG_LEVEL_INFO);

int ipc_process_on_core(uint32_t core)
int ipc_process_on_core(uint32_t core, bool blocking)
{
struct ipc *ipc = ipc_get();
struct idc_msg msg = { .header = IDC_MSG_IPC, .core = core, };
int ret;

Expand All @@ -49,8 +50,19 @@ int ipc_process_on_core(uint32_t core)
return -EACCES;
}

/* The other core will write there its response */
dcache_invalidate_region((void *)MAILBOX_HOSTBOX_BASE,
((struct sof_ipc_cmd_hdr *)ipc->comp_data)->size);

/*
* If the primary core is waiting for secondary cores to complete, it
* will also reply to the host
*/
if (!blocking)
ipc->core = core;

/* send IDC message */
ret = idc_send_msg(&msg, IDC_BLOCKING);
ret = idc_send_msg(&msg, blocking ? IDC_BLOCKING : IDC_NON_BLOCKING);
if (ret < 0)
return ret;

Expand Down
18 changes: 14 additions & 4 deletions src/ipc/ipc3/dai.c
Original file line number Diff line number Diff line change
Expand Up @@ -191,17 +191,27 @@ int ipc_comp_dai_config(struct ipc *ipc, struct ipc_config_dai *common_config,
if (!comp_on_core[i])
continue;

ret = ipc_process_on_core(i);
/*
* TODO: can secondary cores execute dai_config() in
* parallel? Then we could just wait for the last of
* them. For now execute them sequentially.
*/
ret = ipc_process_on_core(i, true);
if (ret < 0)
return ret;
break;

/* check whether IPC failed on secondary core */
mailbox_hostbox_read(&reply, sizeof(reply), 0,
sizeof(reply));
if (reply.error < 0)
if (reply.error < 0) {
/* error reply already written */
return 1;
ret = 1;
break;
}
}

/* We have waited until all secondary cores configured their DAIs */
ipc->core = PLATFORM_PRIMARY_CORE_ID;
}

return ret;
Expand Down
21 changes: 13 additions & 8 deletions src/ipc/ipc3/handler.c
Original file line number Diff line number Diff line change
Expand Up @@ -207,7 +207,7 @@ static int ipc_stream_pcm_params(uint32_t stream)

/* check core */
if (!cpu_is_me(pcm_dev->core))
return ipc_process_on_core(pcm_dev->core);
return ipc_process_on_core(pcm_dev->core, false);

tr_dbg(&ipc_tr, "ipc: comp %d -> params", pcm_params.comp_id);

Expand Down Expand Up @@ -319,7 +319,7 @@ static int ipc_stream_pcm_free(uint32_t header)

/* check core */
if (!cpu_is_me(pcm_dev->core))
return ipc_process_on_core(pcm_dev->core);
return ipc_process_on_core(pcm_dev->core, false);

tr_dbg(&ipc_tr, "ipc: comp %d -> free", free_req.comp_id);

Expand Down Expand Up @@ -356,7 +356,7 @@ static int ipc_stream_position(uint32_t header)

/* check core */
if (!cpu_is_me(pcm_dev->core))
return ipc_process_on_core(pcm_dev->core);
return ipc_process_on_core(pcm_dev->core, false);

tr_info(&ipc_tr, "ipc: comp %d -> position", stream.comp_id);

Expand Down Expand Up @@ -405,7 +405,7 @@ static int ipc_stream_trigger(uint32_t header)

/* check core */
if (!cpu_is_me(pcm_dev->core))
return ipc_process_on_core(pcm_dev->core);
return ipc_process_on_core(pcm_dev->core, false);

tr_dbg(&ipc_tr, "ipc: comp %d -> trigger cmd 0x%x",
stream.comp_id, ipc_command);
Expand Down Expand Up @@ -1109,7 +1109,7 @@ static int ipc_comp_value(uint32_t header, uint32_t cmd)

/* check core */
if (!cpu_is_me(comp_dev->core))
return ipc_process_on_core(comp_dev->core);
return ipc_process_on_core(comp_dev->core, false);

tr_dbg(&ipc_tr, "ipc: comp %d -> cmd %d", data->comp_id, data->cmd);

Expand Down Expand Up @@ -1169,7 +1169,7 @@ static int ipc_glb_tplg_comp_new(uint32_t header)

/* check core */
if (!cpu_is_me(comp->core))
return ipc_process_on_core(comp->core);
return ipc_process_on_core(comp->core, false);

tr_dbg(&ipc_tr, "ipc: pipe %d comp %d -> new (type %d)",
comp->pipeline_id, comp->id, comp->type);
Expand Down Expand Up @@ -1205,7 +1205,7 @@ static int ipc_glb_tplg_buffer_new(uint32_t header)

/* check core */
if (!cpu_is_me(ipc_buffer.comp.core))
return ipc_process_on_core(ipc_buffer.comp.core);
return ipc_process_on_core(ipc_buffer.comp.core, false);

tr_dbg(&ipc_tr, "ipc: pipe %d buffer %d -> new (0x%x bytes)",
ipc_buffer.comp.pipeline_id, ipc_buffer.comp.id,
Expand Down Expand Up @@ -1242,7 +1242,7 @@ static int ipc_glb_tplg_pipe_new(uint32_t header)

/* check core */
if (!cpu_is_me(ipc_pipeline.core))
return ipc_process_on_core(ipc_pipeline.core);
return ipc_process_on_core(ipc_pipeline.core, false);

tr_dbg(&ipc_tr, "ipc: pipe %d -> new", ipc_pipeline.pipeline_id);

Expand Down Expand Up @@ -1495,6 +1495,7 @@ void ipc_boot_complete_msg(ipc_cmd_hdr *header, uint32_t *data)
void ipc_cmd(ipc_cmd_hdr *_hdr)
{
struct sof_ipc_cmd_hdr *hdr = ipc_from_hdr(_hdr);
struct ipc *ipc = ipc_get();
struct sof_ipc_reply reply;
uint32_t type = 0;
int ret;
Expand All @@ -1505,6 +1506,10 @@ void ipc_cmd(ipc_cmd_hdr *_hdr)
goto out;
}

if (!cpu_is_secondary(cpu_get_id()))
/* A new IPC from the host, delivered to the primary core */
ipc->core = PLATFORM_PRIMARY_CORE_ID;

type = iGS(hdr->cmd);

switch (type) {
Expand Down
12 changes: 6 additions & 6 deletions src/ipc/ipc3/helper.c
Original file line number Diff line number Diff line change
Expand Up @@ -513,7 +513,7 @@ int ipc_pipeline_free(struct ipc *ipc, uint32_t comp_id)

/* check core */
if (!cpu_is_me(ipc_pipe->core))
return ipc_process_on_core(ipc_pipe->core);
return ipc_process_on_core(ipc_pipe->core, false);

/* free buffer and remove from list */
ret = pipeline_free(ipc_pipe->pipeline);
Expand Down Expand Up @@ -548,7 +548,7 @@ int ipc_pipeline_complete(struct ipc *ipc, uint32_t comp_id)

/* check core */
if (!cpu_is_me(ipc_pipe->core))
return ipc_process_on_core(ipc_pipe->core);
return ipc_process_on_core(ipc_pipe->core, false);

p = ipc_pipe->pipeline;

Expand Down Expand Up @@ -653,7 +653,7 @@ int ipc_buffer_free(struct ipc *ipc, uint32_t buffer_id)

/* check core */
if (!cpu_is_me(ibd->core))
return ipc_process_on_core(ibd->core);
return ipc_process_on_core(ibd->core, false);

/* try to find sink/source components to check if they still exists */
list_for_item(clist, &ipc->comp_list) {
Expand Down Expand Up @@ -707,7 +707,7 @@ static int ipc_comp_to_buffer_connect(struct ipc_comp_dev *comp,
int ret;

if (!cpu_is_me(comp->core))
return ipc_process_on_core(comp->core);
return ipc_process_on_core(comp->core, false);

tr_dbg(&ipc_tr, "ipc: comp sink %d, source %d -> connect", buffer->id,
comp->id);
Expand Down Expand Up @@ -739,7 +739,7 @@ static int ipc_buffer_to_comp_connect(struct ipc_comp_dev *buffer,
int ret;

if (!cpu_is_me(comp->core))
return ipc_process_on_core(comp->core);
return ipc_process_on_core(comp->core, false);

tr_dbg(&ipc_tr, "ipc: comp sink %d, source %d -> connect", comp->id,
buffer->id);
Expand Down Expand Up @@ -856,7 +856,7 @@ int ipc_comp_free(struct ipc *ipc, uint32_t comp_id)

/* check core */
if (!cpu_is_me(icd->core))
return ipc_process_on_core(icd->core);
return ipc_process_on_core(icd->core, false);

/* check state */
if (icd->cd->state != COMP_STATE_READY)
Expand Down