ASoC: SOF: ipc4: Add decoder for RESOURCE_EVENT notifications from firmware

Decode and print out the content of currently supported RESOURCE_EVENT
notifications from firmware along with the needed data structures and
definitions.

Signed-off-by: Peter Ujfalusi <peter.ujfalusi@linux.intel.com>
Reviewed-by: Bard Liao <yung-chuan.liao@linux.intel.com>
Reviewed-by: Liam Girdwood <liam.r.girdwood@intel.com>
Link: https://patch.msgid.link/20260730082444.4828-1-peter.ujfalusi@linux.intel.com
Signed-off-by: Mark Brown <broonie@kernel.org>
This commit is contained in:
Peter Ujfalusi 2026-07-30 11:24:44 +03:00 committed by Mark Brown
parent cd88e3d3e1
commit c50ed4627e
No known key found for this signature in database
GPG Key ID: 24D68B725D5487D0
2 changed files with 136 additions and 1 deletions

View File

@ -536,12 +536,63 @@ enum sof_ipc4_notification_type {
SOF_IPC4_NOTIFY_TYPE_LAST,
};
enum sof_ipc4_resource_type {
SOF_IPC4_MODULE_INSTANCE,
SOF_IPC4_PIPELINE,
SOF_IPC4_GATEWAY,
SOF_IPC4_EDF_TASK,
SOF_IPC4_INVALID_RESOURCE_TYPE,
};
enum sof_ipc4_event_type {
/* Underrun detected by the Mixer */
SOF_IPC4_MIXER_UNDERRUN_DETECTED = 1,
/* Error caught during data processing */
SOF_IPC4_PROCESS_DATA_ERROR = 3,
/* Underrun detected by gateway. */
SOF_IPC4_GATEWAY_UNDERRUN_DETECTED = 6,
/* Overrun detected by gateway */
SOF_IPC4_GATEWAY_OVERRUN_DETECTED,
};
/**
* struct sof_ipc4_process_data_error_event_data - process data error event payload
* @error_code: Error code returned by data processing function
*/
struct sof_ipc4_process_data_error_event_data {
uint32_t error_code;
};
/**
* struct sof_ipc4_mixer_underrun_event_data - mixer underrun event payload
* @eos_flag: Indicates EndOfStream
* @data_mixed: Data processed by module (in bytes)
* @expected_data_mixed: Expected data to be processed (in bytes)
*/
struct sof_ipc4_mixer_underrun_event_data {
uint32_t eos_flag;
uint32_t data_mixed;
uint32_t expected_data_mixed;
};
/**
* union sof_ipc4_resource_event_data - resource event specific payload
* @dws: Raw event data payload as six dwords
* @process_data_error: SOF_IPC4_PROCESS_DATA_ERROR payload
* @mixer_underrun: SOF_IPC4_MIXER_UNDERRUN_DETECTED payload
*/
union sof_ipc4_resource_event_data {
uint32_t dws[6];
struct sof_ipc4_process_data_error_event_data process_data_error;
struct sof_ipc4_mixer_underrun_event_data mixer_underrun;
};
struct sof_ipc4_notify_resource_data {
uint32_t resource_type;
uint32_t resource_id;
uint32_t event_type;
uint32_t reserved;
uint32_t data[6];
union sof_ipc4_resource_event_data data;
} __packed __aligned(4);
#define SOF_IPC4_DEBUG_DESCRIPTOR_SIZE 12 /* 3 x u32 */

View File

@ -289,6 +289,89 @@ static void sof_ipc4_dump_payload(struct snd_sof_dev *sdev,
16, 4, ipc_data, size, false);
}
static const char *sof_ipc4_resource_type_str(u32 type)
{
switch (type) {
case SOF_IPC4_MODULE_INSTANCE:
return "resource: MODULE_INSTANCE";
case SOF_IPC4_PIPELINE:
return "resource: PIPELINE";
case SOF_IPC4_GATEWAY:
return "resource: GATEWAY";
case SOF_IPC4_EDF_TASK:
return "resource: EDF_TASK";
case SOF_IPC4_INVALID_RESOURCE_TYPE:
return "Resource is invalid";
default:
return "Unknown resource type";
}
}
static const char *sof_ipc4_resource_event_type_str(u32 event_type)
{
switch (event_type) {
case SOF_IPC4_MIXER_UNDERRUN_DETECTED:
return "event: MIXER_UNDERRUN_DETECTED";
case SOF_IPC4_PROCESS_DATA_ERROR:
return "event: PROCESS_DATA_ERROR";
case SOF_IPC4_GATEWAY_UNDERRUN_DETECTED:
return "event: GATEWAY_UNDERRUN_DETECTED";
case SOF_IPC4_GATEWAY_OVERRUN_DETECTED:
return "event: GATEWAY_OVERRUN_DETECTED";
default:
return "Unknown event type";
}
}
static void sof_ipc4_resource_event_handler(struct snd_sof_dev *sdev,
struct sof_ipc4_msg *ipc4_msg)
{
struct sof_ipc4_notify_resource_data *data = ipc4_msg->data_ptr;
/* Print event details */
switch (data->event_type) {
case SOF_IPC4_MIXER_UNDERRUN_DETECTED:
dev_dbg(sdev->dev, "%s (%u): eos %u, mixed %u, expected %u\n",
sof_ipc4_resource_event_type_str(data->event_type),
data->event_type, data->data.mixer_underrun.eos_flag,
data->data.mixer_underrun.data_mixed,
data->data.mixer_underrun.expected_data_mixed);
break;
case SOF_IPC4_PROCESS_DATA_ERROR:
dev_dbg(sdev->dev, "%s (%u): error_code %#x\n",
sof_ipc4_resource_event_type_str(data->event_type),
data->event_type, data->data.process_data_error.error_code);
break;
case SOF_IPC4_GATEWAY_UNDERRUN_DETECTED:
case SOF_IPC4_GATEWAY_OVERRUN_DETECTED:
dev_dbg(sdev->dev, "%s (%u)\n",
sof_ipc4_resource_event_type_str(data->event_type),
data->event_type);
break;
default:
dev_dbg(sdev->dev, "%s (%u): raw dws %#x %#x %#x %#x %#x %#x\n",
sof_ipc4_resource_event_type_str(data->event_type),
data->event_type,
data->data.dws[0], data->data.dws[1], data->data.dws[2],
data->data.dws[3], data->data.dws[4], data->data.dws[5]);
break;
}
/* Print resource details */
if (data->resource_type == SOF_IPC4_MODULE_INSTANCE) {
u32 module_id = SOF_IPC4_MOD_ID_GET(data->resource_id);
u32 instance_id = SOF_IPC4_MOD_INSTANCE_GET(data->resource_id);
dev_dbg(sdev->dev, "%s (%u), module_id %u, instance_id %u\n",
sof_ipc4_resource_type_str(data->resource_type),
data->resource_type, module_id, instance_id);
} else if (data->resource_type != SOF_IPC4_INVALID_RESOURCE_TYPE) {
dev_dbg(sdev->dev, "%s (%u), id %u\n",
sof_ipc4_resource_type_str(data->resource_type),
data->resource_type, data->resource_id);
}
}
static int sof_ipc4_get_reply(struct snd_sof_dev *sdev)
{
struct snd_sof_ipc_msg *msg = sdev->msg;
@ -734,6 +817,7 @@ static void sof_ipc4_rx_msg(struct snd_sof_dev *sdev)
break;
case SOF_IPC4_NOTIFY_RESOURCE_EVENT:
data_size = sizeof(struct sof_ipc4_notify_resource_data);
handler_func = sof_ipc4_resource_event_handler;
break;
case SOF_IPC4_NOTIFY_LOG_BUFFER_STATUS:
sof_ipc4_mtrace_update_pos(sdev, SOF_IPC4_LOG_CORE_GET(ipc4_msg->primary));