From 25d2e1207a4cec5c4276377d4324c60a679a9cae Mon Sep 17 00:00:00 2001 From: Jyri Sarha Date: Sat, 16 Nov 2024 00:51:55 +0200 Subject: [PATCH] ASoC: SOF: sof-client-probes-ipc4: Human readable debugfs "probe_points" The current output of three integers is not very human readable. Use ipc4 functions to describe in more detail what the struct sof_probe_point_desc buffer_id is actually referring to in an ipc4 SOF system. Before this commit the "probe_points" debugfs file could read as: Id: 0x01000004 Purpose: 0 Node id: 0x100 Id: 0x00000006 Purpose: 0 Node id: 0x100 And after in the same situation in an ipc4 system it reads: 16777220,0,256 host-copier.0.playback output buf idx 0 (probed) 6,0,256 gain.1.1 input buf idx 0 (probed) The triplet in the beginning of the line can be used to reinserted the probe point again by writing it into "probe_points" debugfs file, if its first removed by writing the fist number in "probe_points_remove". The last number is ignored when creating a probe point. Signed-off-by: Jyri Sarha --- sound/soc/sof/sof-client-probes-ipc4.c | 60 ++++++++++++++++++++++++++ sound/soc/sof/sof-client-probes.c | 16 +++++-- sound/soc/sof/sof-client-probes.h | 2 + 3 files changed, 75 insertions(+), 3 deletions(-) diff --git a/sound/soc/sof/sof-client-probes-ipc4.c b/sound/soc/sof/sof-client-probes-ipc4.c index 7c710ebe81bb8c..802c16e82619f5 100644 --- a/sound/soc/sof/sof-client-probes-ipc4.c +++ b/sound/soc/sof/sof-client-probes-ipc4.c @@ -8,6 +8,7 @@ #include #include #include +#include "sof-audio.h" #include "sof-priv.h" #include "ipc4-priv.h" #include "sof-client.h" @@ -49,6 +50,15 @@ enum sof_ipc4_probe_type { SOF_IPC4_PROBE_TYPE_INTERNAL }; +#define SOF_IPC4_PROBE_TYPE_SHIFT 24 +#define SOF_IPC4_PROBE_TYPE_MASK GENMASK(25, 24) +#define SOF_IPC4_PROBE_TYPE_GET(x) (((x) & SOF_IPC4_PROBE_TYPE_MASK) \ + >> SOF_IPC4_PROBE_TYPE_SHIFT) +#define SOF_IPC4_PROBE_IDX_SHIFT 26 +#define SOF_IPC4_PROBE_IDX_MASK GENMASK(31, 26) +#define SOF_IPC4_PROBE_IDX_GET(x) (((x) & SOF_IPC4_PROBE_IDX_MASK) \ + >> SOF_IPC4_PROBE_IDX_SHIFT) + struct sof_ipc4_probe_point { u32 point_id; u32 purpose; @@ -62,6 +72,20 @@ struct sof_ipc4_probe_info { #define INVALID_PIPELINE_ID 0xFF +static const char *sof_probe_ipc4_type_string(u32 type) +{ + switch (type) { + case SOF_IPC4_PROBE_TYPE_INPUT: + return "input"; + case SOF_IPC4_PROBE_TYPE_OUTPUT: + return "output"; + case SOF_IPC4_PROBE_TYPE_INTERNAL: + return "internal"; + default: + return "UNKNOWN"; + } +} + /** * sof_ipc4_probe_get_module_info - Get IPC4 module info for probe module * @cdev: SOF client device @@ -224,6 +248,41 @@ static int ipc4_probes_points_info(struct sof_client_dev *cdev, return 0; } +/** + * ipc4_probes_point_print - Human readable print of probe point descriptor + * @cdev: SOF client device + * @buf: Buffer to print to + * @size: Available bytes in buffer + * @desc: Describes the probe point to print + * @return: Number of bytes printed or an error code (snprintf return value) + */ +static int ipc4_probes_point_print(struct sof_client_dev *cdev, char *buf, size_t size, + struct sof_probe_point_desc *desc) +{ + struct device *dev = &cdev->auxdev.dev; + struct snd_sof_widget *swidget; + int ret; + + swidget = sof_client_ipc4_find_swidget_by_id(cdev, SOF_IPC4_MOD_ID_GET(desc->buffer_id), + SOF_IPC4_MOD_INSTANCE_GET(desc->buffer_id)); + if (!swidget) { + dev_err(dev, "%s: Failed to find widget for module %lu.%lu\n", + __func__, SOF_IPC4_MOD_ID_GET(desc->buffer_id), + SOF_IPC4_MOD_INSTANCE_GET(desc->buffer_id)); + ret = snprintf(buf, size, "%u,%u,%u\tUNKNOWN buffer_id 0x%08x\n", + desc->buffer_id, desc->purpose, desc->stream_tag, + desc->buffer_id); + return ret; + } + + ret = snprintf(buf, size, "%u,%u,%u\t%s %s buf idx %lu %s\n", + desc->buffer_id, desc->purpose, desc->stream_tag, swidget->widget->name, + sof_probe_ipc4_type_string(SOF_IPC4_PROBE_TYPE_GET(desc->buffer_id)), + SOF_IPC4_PROBE_IDX_GET(desc->buffer_id), + desc->stream_tag ? "(connected)" : ""); + return ret; +} + /** * ipc4_probes_points_add - connect specified probes * @cdev: SOF client device @@ -328,6 +387,7 @@ const struct sof_probes_ipc_ops ipc4_probe_ops = { .init = ipc4_probes_init, .deinit = ipc4_probes_deinit, .points_info = ipc4_probes_points_info, + .point_print = ipc4_probes_point_print, .points_add = ipc4_probes_points_add, .points_remove = ipc4_probes_points_remove, }; diff --git a/sound/soc/sof/sof-client-probes.c b/sound/soc/sof/sof-client-probes.c index aff9ce98042954..1bc691d208e241 100644 --- a/sound/soc/sof/sof-client-probes.c +++ b/sound/soc/sof/sof-client-probes.c @@ -17,8 +17,14 @@ #include #include +#include #include "sof-client.h" #include "sof-client-probes.h" +#include "sof-audio.h" + +#ifdef CONFIG_SND_SOC_SOF_IPC4 +#include "ipc4-priv.h" +#endif #define SOF_PROBES_SUSPEND_DELAY_MS 3000 /* only extraction supported for now */ @@ -223,9 +229,13 @@ static ssize_t sof_probes_dfs_points_read(struct file *file, char __user *to, for (i = 0; i < num_desc; i++) { offset = strlen(buf); remaining = PAGE_SIZE - offset; - ret = snprintf(buf + offset, remaining, - "Id: %#010x Purpose: %u Node id: %#x\n", - desc[i].buffer_id, desc[i].purpose, desc[i].stream_tag); + if (ipc->point_print) + ret = ipc->point_print(cdev, buf + offset, remaining, &desc[i]); + else + ret = snprintf(buf + offset, remaining, + "Id: %#010x Purpose: %u Node id: %#x\n", + desc[i].buffer_id, desc[i].purpose, desc[i].stream_tag); + if (ret < 0 || ret >= remaining) { /* truncate the output buffer at the last full line */ buf[offset] = '\0'; diff --git a/sound/soc/sof/sof-client-probes.h b/sound/soc/sof/sof-client-probes.h index da04d65b8d995e..c445e435aa35bd 100644 --- a/sound/soc/sof/sof-client-probes.h +++ b/sound/soc/sof/sof-client-probes.h @@ -41,6 +41,8 @@ struct sof_probes_ipc_ops { int (*points_info)(struct sof_client_dev *cdev, struct sof_probe_point_desc **desc, size_t *num_desc); + int (*point_print)(struct sof_client_dev *cdev, char *buf, size_t size, + struct sof_probe_point_desc *desc); int (*points_add)(struct sof_client_dev *cdev, struct sof_probe_point_desc *desc, size_t num_desc);