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
9 changes: 9 additions & 0 deletions src/audio/pipeline/pipeline-graph.c
Original file line number Diff line number Diff line change
Expand Up @@ -558,6 +558,15 @@ struct comp_dev *pipeline_get_dai_comp_latency(uint32_t pipeline_id, uint32_t *l
if (!source || !source->pipeline)
return NULL;

/* As pipeline data is allocated in cached space, continue calculation for next
* connected pipeline only if that pipeline is on same core.
* This is a workaround, the real solution would be to use something like
* process_on_core() to continue calculation on required core. However, as this
* "latency feature" seems never used anyway, this workaround could be enough.
*/
if (!cpu_is_me(source->ipc_config.core))
return NULL;

/* Get a next sink component */
ipc_sink = ipc_get_ppl_sink_comp(ipc, source->pipeline->pipeline_id);
}
Expand Down
61 changes: 61 additions & 0 deletions src/idc/idc.c
Original file line number Diff line number Diff line change
Expand Up @@ -126,6 +126,56 @@ static void idc_ipc(void)
ipc_cmd(ipc->comp_data);
}

#if CONFIG_IPC_MAJOR_4
static int idc_ipc4_bind(uint32_t comp_id)
{
struct ipc_comp_dev *ipc_dev;
struct idc_payload *payload;
struct ipc4_module_bind_unbind *bu;

ipc_dev = ipc_get_comp_by_id(ipc_get(), comp_id);
if (!ipc_dev)
return -ENODEV;

payload = idc_payload_get(*idc_get(), cpu_get_id());
Comment thread
serhiy-katsyuba-intel marked this conversation as resolved.
Resolved
bu = (struct ipc4_module_bind_unbind *)payload;

return comp_bind(ipc_dev->cd, bu);
}

static int idc_ipc4_unbind(uint32_t comp_id)
{
struct ipc_comp_dev *ipc_dev;
struct idc_payload *payload;
struct ipc4_module_bind_unbind *bu;

ipc_dev = ipc_get_comp_by_id(ipc_get(), comp_id);
if (!ipc_dev)
return -ENODEV;

payload = idc_payload_get(*idc_get(), cpu_get_id());
bu = (struct ipc4_module_bind_unbind *)payload;

return comp_unbind(ipc_dev->cd, bu);
}

static int idc_get_attribute(uint32_t comp_id)
{
struct ipc_comp_dev *ipc_dev;
struct idc_payload *idc_payload;
struct get_attribute_remote_payload *get_attr_payload;

ipc_dev = ipc_get_comp_by_id(ipc_get(), comp_id);
if (!ipc_dev)
return -ENODEV;

idc_payload = idc_payload_get(*idc_get(), cpu_get_id());
get_attr_payload = (struct get_attribute_remote_payload *)idc_payload;

return comp_get_attribute(ipc_dev->cd, get_attr_payload->type, get_attr_payload->value);
}
#endif /* CONFIG_IPC_MAJOR_4 */

/**
* \brief Executes IDC component params message.
* \param[in] comp_id Component id to have params set.
Expand Down Expand Up @@ -327,6 +377,17 @@ void idc_cmd(struct idc_msg *msg)
case iTS(IDC_MSG_IPC):
idc_ipc();
break;
#if CONFIG_IPC_MAJOR_4
case iTS(IDC_MSG_BIND):
ret = idc_ipc4_bind(msg->extension);
break;
case iTS(IDC_MSG_UNBIND):
ret = idc_ipc4_unbind(msg->extension);
break;
case iTS(IDC_MSG_GET_ATTRIBUTE):
ret = idc_get_attribute(msg->extension);
break;
#endif
case iTS(IDC_MSG_PARAMS):
ret = idc_params(msg->extension);
break;
Expand Down
84 changes: 84 additions & 0 deletions src/include/sof/audio/component_ext.h
Original file line number Diff line number Diff line change
Expand Up @@ -208,15 +208,61 @@ static inline int comp_prepare(struct comp_dev *dev)

int comp_copy(struct comp_dev *dev);

#if CONFIG_IPC_MAJOR_4
struct get_attribute_remote_payload {
uint32_t type;
void *value;
};

static inline int comp_ipc4_get_attribute_remote(struct comp_dev *dev, uint32_t type,
void *value)
{
struct ipc4_base_module_cfg *base_cfg;
struct get_attribute_remote_payload payload = {};
struct idc_msg msg = { IDC_MSG_GET_ATTRIBUTE,
IDC_EXTENSION(dev->ipc_config.id), dev->ipc_config.core,
sizeof(payload), &payload};
int ret;

/* Only COMP_ATTR_BASE_CONFIG is supported for remote access */
if (type != COMP_ATTR_BASE_CONFIG)
return -EINVAL;

base_cfg = rzalloc(SOF_MEM_ZONE_RUNTIME_SHARED, 0, SOF_MEM_CAPS_RAM, sizeof(*base_cfg));
if (!base_cfg)
return -ENOMEM;

payload.type = type;
payload.value = base_cfg;

ret = idc_send_msg(&msg, IDC_BLOCKING);

if (ret == 0)
memcpy_s(value, sizeof(struct ipc4_base_module_cfg),
base_cfg, sizeof(struct ipc4_base_module_cfg));

rfree(base_cfg);
return ret;
}
#endif /* CONFIG_IPC_MAJOR_4 */

/** See comp_ops::get_attribute */
static inline int comp_get_attribute(struct comp_dev *dev, uint32_t type,
void *value)
{
#if CONFIG_IPC_MAJOR_4

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

better to have two copies of comp_get_attribute, 1 for ipc3 and the other for ipc4 (and this way we can put the ipc4 version with all the other ipc4 code in teh header under a single ifdef).

if (dev->drv->ops.get_attribute)
return cpu_is_me(dev->ipc_config.core) ?
dev->drv->ops.get_attribute(dev, type, value) :
comp_ipc4_get_attribute_remote(dev, type, value);

return 0;
#else
if (dev->drv->ops.get_attribute)
return dev->drv->ops.get_attribute(dev, type, value);

return 0;
#endif
}

/** See comp_ops::set_attribute */
Expand Down Expand Up @@ -386,24 +432,62 @@ static inline struct comp_driver_list *comp_drivers_get(void)
return sof_get()->comp_drivers;
}

#if CONFIG_IPC_MAJOR_4
static inline int comp_ipc4_bind_remote(struct comp_dev *dev, void *data)
{
struct idc_msg msg = { IDC_MSG_BIND,
IDC_EXTENSION(dev->ipc_config.id), dev->ipc_config.core,
sizeof(struct ipc4_module_bind_unbind), data};

return idc_send_msg(&msg, IDC_BLOCKING);
}
#endif

static inline int comp_bind(struct comp_dev *dev, void *data)
{
#if CONFIG_IPC_MAJOR_4
if (dev->drv->ops.bind)
return cpu_is_me(dev->ipc_config.core) ?
dev->drv->ops.bind(dev, data) : comp_ipc4_bind_remote(dev, data);

return 0;
#else
int ret = 0;

if (dev->drv->ops.bind)
ret = dev->drv->ops.bind(dev, data);

return ret;
#endif
}

#if CONFIG_IPC_MAJOR_4
static inline int comp_ipc4_unbind_remote(struct comp_dev *dev, void *data)
{
struct idc_msg msg = { IDC_MSG_UNBIND,
IDC_EXTENSION(dev->ipc_config.id), dev->ipc_config.core,
sizeof(struct ipc4_module_bind_unbind), data};

return idc_send_msg(&msg, IDC_BLOCKING);
}
#endif

static inline int comp_unbind(struct comp_dev *dev, void *data)
{
#if CONFIG_IPC_MAJOR_4
if (dev->drv->ops.unbind)
return cpu_is_me(dev->ipc_config.core) ?
dev->drv->ops.unbind(dev, data) : comp_ipc4_unbind_remote(dev, data);

return 0;
#else
int ret = 0;

if (dev->drv->ops.unbind)
ret = dev->drv->ops.unbind(dev, data);

return ret;
#endif
}

static inline uint64_t comp_get_total_data_processed(struct comp_dev *dev, uint32_t stream_no,
Expand Down
4 changes: 4 additions & 0 deletions xtos/include/rtos/idc.h
Original file line number Diff line number Diff line change
Expand Up @@ -101,6 +101,10 @@
#define IDC_MSG_AMS IDC_TYPE(0xB)
#define IDC_MSG_AMS_EXT IDC_EXTENSION(0x0)

#define IDC_MSG_BIND IDC_TYPE(0xD)
#define IDC_MSG_UNBIND IDC_TYPE(0xE)
#define IDC_MSG_GET_ATTRIBUTE IDC_TYPE(0xF)

#define IDC_HEADER_TO_AMS_SLOT_MASK(x) (x & 0xFFFF)

/** \brief IDC_MSG_SECONDARY_CORE_CRASHED header fields. */
Expand Down
4 changes: 4 additions & 0 deletions zephyr/include/rtos/idc.h
Original file line number Diff line number Diff line change
Expand Up @@ -102,6 +102,10 @@

#define IDC_HEADER_TO_AMS_SLOT_MASK(x) (x & 0xFFFF)

#define IDC_MSG_BIND IDC_TYPE(0xD)
#define IDC_MSG_UNBIND IDC_TYPE(0xE)
#define IDC_MSG_GET_ATTRIBUTE IDC_TYPE(0xF)

/** \brief IDC_MSG_SECONDARY_CORE_CRASHED header fields. */
#define IDC_SCC_CORE_SHIFT 0
#define IDC_SCC_CORE_MASK 0xff
Expand Down