Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Probes ipc4 get config #5249

Open
wants to merge 5 commits into
base: topic/sof-dev
Choose a base branch
from
Open
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
4 changes: 4 additions & 0 deletions include/sound/sof/ipc4/header.h
Original file line number Diff line number Diff line change
Expand Up @@ -326,10 +326,14 @@ struct sof_ipc4_base_module_cfg {
#define SOF_IPC4_MOD_INSTANCE_SHIFT 16
#define SOF_IPC4_MOD_INSTANCE_MASK GENMASK(23, 16)
#define SOF_IPC4_MOD_INSTANCE(x) ((x) << SOF_IPC4_MOD_INSTANCE_SHIFT)
#define SOF_IPC4_MOD_INSTANCE_GET(x) (((x) & SOF_IPC4_MOD_INSTANCE_MASK) \
>> SOF_IPC4_MOD_INSTANCE_SHIFT)

#define SOF_IPC4_MOD_ID_SHIFT 0
#define SOF_IPC4_MOD_ID_MASK GENMASK(15, 0)
#define SOF_IPC4_MOD_ID(x) ((x) << SOF_IPC4_MOD_ID_SHIFT)
#define SOF_IPC4_MOD_ID_GET(x) (((x) & SOF_IPC4_MOD_ID_MASK) \
>> SOF_IPC4_MOD_ID_SHIFT)

/* init module ipc msg */
#define SOF_IPC4_MOD_EXT_PARAM_SIZE_SHIFT 0
Expand Down
25 changes: 18 additions & 7 deletions sound/soc/sof/sof-client-probes-ipc3.c
Original file line number Diff line number Diff line change
Expand Up @@ -100,9 +100,11 @@ static int ipc3_probes_deinit(struct sof_client_dev *cdev)
}

static int ipc3_probes_info(struct sof_client_dev *cdev, unsigned int cmd,
void **params, size_t *num_params)
void **params, size_t *num_params,
enum sof_probe_info_type type)
{
size_t max_msg_size = sof_client_get_ipc_max_payload_size(cdev);
struct device *dev = &cdev->auxdev.dev;
struct sof_ipc_probe_info_params msg = {{{0}}};
struct sof_ipc_probe_info_params *reply;
size_t bytes;
Expand All @@ -111,6 +113,11 @@ static int ipc3_probes_info(struct sof_client_dev *cdev, unsigned int cmd,
*params = NULL;
*num_params = 0;

if (type != PROBES_INFO_ACTIVE_PROBES) {
ujfalusi marked this conversation as resolved.
Show resolved Hide resolved
dev_err(dev, "%s: info type %u not supported", __func__, type);
return -EOPNOTSUPP;
}

reply = kzalloc(max_msg_size, GFP_KERNEL);
if (!reply)
return -ENOMEM;
Expand Down Expand Up @@ -142,21 +149,25 @@ static int ipc3_probes_info(struct sof_client_dev *cdev, unsigned int cmd,
}

/**
* ipc3_probes_points_info - retrieve list of active probe points
* ipc3_probes_points_info - retrieve list of probe points
* @cdev: SOF client device
* @desc: Returned list of active probes
* @num_desc: Returned count of active probes
* @type: Either PROBES_INFO_ACTIVE_PROBES or PROBES_INFO_AVAILABE_PROBES
*
* If type is PROBES_INFO_ACTIVE_PROBES, host sends PROBE_POINT_INFO
* request to obtain list of active probe points, valid for
* disconnection when given probe is no longer required.
*
* Host sends PROBE_POINT_INFO request to obtain list of active probe
* points, valid for disconnection when given probe is no longer
* required.
* Type PROBES_INFO_AVAILABE_PROBES is not yet supported.
*/
static int ipc3_probes_points_info(struct sof_client_dev *cdev,
struct sof_probe_point_desc **desc,
size_t *num_desc)
size_t *num_desc,
enum sof_probe_info_type type)
{
return ipc3_probes_info(cdev, SOF_IPC_PROBE_POINT_INFO,
(void **)desc, num_desc);
(void **)desc, num_desc, type);
}

/**
Expand Down
133 changes: 126 additions & 7 deletions sound/soc/sof/sof-client-probes-ipc4.c
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
#include <sound/soc.h>
#include <sound/sof/ipc4/header.h>
#include <uapi/sound/sof/header.h>
#include "sof-audio.h"
Copy link
Member

Choose a reason for hiding this comment

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

@jsarha btw the 1st triplet above 16777220,0,256 is better in HEX as 0x1000004, 0x0, 0x100

Copy link
Author

Choose a reason for hiding this comment

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

@lgirdwood , the reason for the decimal format is the the fackt that its decimal numbers that are expected when defining the probe points. So if we want to be able to copy-paste the triplets to probe_points debgfs file, then we want to print decimal numbers. We can of course change the write interface too so that it expect hex-numbers or is sensitive to "0x" prefix. It would take a day or two to implement and properly test that, should I go that way?

Copy link
Member

Choose a reason for hiding this comment

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

Pls make hex, the hex value also make sense when introspection is performed by anyone debugging as they map to bit masks within the IDs, i.e. its not a coincidence we have 0x1000004 and 0x100 as values.

Copy link
Author

Choose a reason for hiding this comment

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

It appears that the input side already supported 0x-prefixed hex inputs. So this was a simple change after all.

#include "sof-priv.h"
#include "ipc4-priv.h"
#include "sof-client.h"
Expand All @@ -28,6 +29,7 @@ enum sof_ipc4_probe_runtime_param {
SOF_IPC4_PROBE_INJECTION_DMA_DETACH,
SOF_IPC4_PROBE_POINTS,
SOF_IPC4_PROBE_POINTS_DISCONNECT,
SOF_IPC4_PROBE_POINTS_AVAILABLE,
};

struct sof_ipc4_probe_gtw_cfg {
Expand All @@ -49,14 +51,42 @@ 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;
u32 stream_tag;
} __packed __aligned(4);

struct sof_ipc4_probe_info {
unsigned int num_elems;
DECLARE_FLEX_ARRAY(struct sof_ipc4_probe_point, points);
} __packed;

#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
Expand Down Expand Up @@ -164,24 +194,112 @@ static int ipc4_probes_deinit(struct sof_client_dev *cdev)
}

/**
* ipc4_probes_points_info - retrieve list of active probe points
* ipc4_probes_points_info - retrieve list of probe points
* @cdev: SOF client device
* @desc: Returned list of active probes
* @num_desc: Returned count of active probes
* @type: Either PROBES_INFO_ACTIVE_PROBES or PROBES_INFO_AVAILABE_PROBES
* @return: 0 on success, negative error code on error
*
* Dummy implementation returning empty list of probes.
* Returns list if active probe points if type is
* PROBES_INFO_ACTIVE_PROBES, or list of all available probe points if
* type is PROBES_INFO_AVAILABE_PROBES.
*/
static int ipc4_probes_points_info(struct sof_client_dev *cdev,
struct sof_probe_point_desc **desc,
size_t *num_desc)
size_t *num_desc,
enum sof_probe_info_type type)
{
/* TODO: Firmware side implementation needed first */
*desc = NULL;
*num_desc = 0;
struct sof_man4_module *mentry = sof_ipc4_probe_get_module_info(cdev);
struct device *dev = &cdev->auxdev.dev;
struct sof_ipc4_probe_info *info;
struct sof_ipc4_msg msg;
u32 param_id;
int i, ret;

if (!mentry)
return -ENODEV;

switch (type) {
case PROBES_INFO_ACTIVE_PROBES:
param_id = SOF_IPC4_PROBE_POINTS;
break;
case PROBES_INFO_AVAILABE_PROBES:
param_id = SOF_IPC4_PROBE_POINTS_AVAILABLE;
break;
default:
dev_err(dev, "%s: info type %u not supported", __func__, type);
return -EOPNOTSUPP;
};

msg.primary = mentry->id;
msg.primary |= SOF_IPC4_MSG_DIR(SOF_IPC4_MSG_REQUEST);
msg.primary |= SOF_IPC4_MSG_TARGET(SOF_IPC4_MODULE_MSG);

msg.extension = SOF_IPC4_MOD_EXT_MSG_PARAM_ID(param_id);

msg.data_size = cdev->sdev->ipc->max_payload_size;
msg.data_ptr = kzalloc(msg.data_size, GFP_KERNEL);
if (!msg.data_ptr)
return -ENOMEM;

ret = sof_client_ipc_set_get_data(cdev, &msg, false);
if (ret) {
kfree(msg.data_ptr);
return ret;
}
info = msg.data_ptr;
*num_desc = info->num_elems;
dev_dbg(dev, "%s: got %zu probe points", __func__, *num_desc);

*desc = kzalloc(*num_desc * sizeof(*desc), GFP_KERNEL);
if (!*desc) {
kfree(msg.data_ptr);
return -ENOMEM;
}

for (i = 0; i < *num_desc; i++) {
(*desc)[i].buffer_id = info->points[i].point_id;
(*desc)[i].purpose = info->points[i].purpose;
(*desc)[i].stream_tag = info->points[i].stream_tag;
}
kfree(msg.data_ptr);

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, "%#x,%#x,%#x\t%s %s buf idx %lu %s\n",
desc->buffer_id, desc->purpose, desc->stream_tag,
swidget ? swidget->widget->name : "<unknown>",
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
Expand All @@ -202,7 +320,7 @@ static int ipc4_probes_points_add(struct sof_client_dev *cdev,
int i, ret;

if (!mentry)
return -ENODEV;
return -EOPNOTSUPP;

/* The sof_probe_point_desc and sof_ipc4_probe_point structs
* are of same size and even the integers are the same in the
Expand Down Expand Up @@ -286,6 +404,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,
};
58 changes: 49 additions & 9 deletions sound/soc/sof/sof-client-probes.c
Original file line number Diff line number Diff line change
Expand Up @@ -17,8 +17,14 @@

#include <sound/soc.h>
#include <sound/sof/header.h>
#include <sound/sof/ipc4/header.h>
#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 */
Expand Down Expand Up @@ -69,7 +75,8 @@ static int sof_probes_compr_shutdown(struct snd_compr_stream *cstream,
int i, ret;

/* disconnect all probe points */
ret = ipc->points_info(cdev, &desc, &num_desc);
ret = ipc->points_info(cdev, &desc, &num_desc,
PROBES_INFO_ACTIVE_PROBES);
ujfalusi marked this conversation as resolved.
Show resolved Hide resolved
if (ret < 0) {
dev_err(dai->dev, "Failed to get probe points: %d\n", ret);
goto exit;
Expand Down Expand Up @@ -189,7 +196,8 @@ static const struct snd_compress_ops sof_probes_compressed_ops = {
};

static ssize_t sof_probes_dfs_points_read(struct file *file, char __user *to,
size_t count, loff_t *ppos)
size_t count, loff_t *ppos,
enum sof_probe_info_type type)
{
struct sof_client_dev *cdev = file->private_data;
struct sof_probes_priv *priv = cdev->data;
Expand All @@ -216,16 +224,20 @@ static ssize_t sof_probes_dfs_points_read(struct file *file, char __user *to,
goto exit;
}

ret = ipc->points_info(cdev, &desc, &num_desc);
ret = ipc->points_info(cdev, &desc, &num_desc, type);
if (ret < 0)
goto pm_error;

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);
jsarha marked this conversation as resolved.
Show resolved Hide resolved

if (ret < 0 || ret >= remaining) {
/* truncate the output buffer at the last full line */
buf[offset] = '\0';
Expand All @@ -248,6 +260,22 @@ static ssize_t sof_probes_dfs_points_read(struct file *file, char __user *to,
return ret;
}

static ssize_t sof_probes_dfs_active_points_read(struct file *file,
char __user *to,
size_t count, loff_t *ppos)
{
return sof_probes_dfs_points_read(file, to, count, ppos,
PROBES_INFO_ACTIVE_PROBES);
}

static ssize_t sof_probes_dfs_available_points_read(struct file *file,
char __user *to,
size_t count, loff_t *ppos)
{
return sof_probes_dfs_points_read(file, to, count, ppos,
PROBES_INFO_AVAILABE_PROBES);
}

static ssize_t
sof_probes_dfs_points_write(struct file *file, const char __user *from,
size_t count, loff_t *ppos)
Expand Down Expand Up @@ -298,15 +326,23 @@ sof_probes_dfs_points_write(struct file *file, const char __user *from,
return ret;
}

static const struct file_operations sof_probes_points_fops = {
static const struct file_operations sof_probes_active_points_fops = {
.open = simple_open,
.read = sof_probes_dfs_points_read,
.read = sof_probes_dfs_active_points_read,
.write = sof_probes_dfs_points_write,
.llseek = default_llseek,

.owner = THIS_MODULE,
};

static const struct file_operations sof_probes_available_points_fops = {
.open = simple_open,
.read = sof_probes_dfs_available_points_read,
.llseek = default_llseek,

.owner = THIS_MODULE,
};

static ssize_t
sof_probes_dfs_points_remove_write(struct file *file, const char __user *from,
size_t count, loff_t *ppos)
Expand Down Expand Up @@ -452,13 +488,17 @@ static int sof_probes_client_probe(struct auxiliary_device *auxdev,

/* create read-write probes_points debugfs entry */
priv->dfs_points = debugfs_create_file("probe_points", 0644, dfsroot,
cdev, &sof_probes_points_fops);
cdev, &sof_probes_active_points_fops);

/* create read-write probe_points_remove debugfs entry */
priv->dfs_points_remove = debugfs_create_file("probe_points_remove", 0644,
dfsroot, cdev,
&sof_probes_points_remove_fops);

/* create read-write probes_points debugfs entry */
priv->dfs_points = debugfs_create_file("probe_points_available", 0644, dfsroot,
cdev, &sof_probes_available_points_fops);

links = devm_kcalloc(dev, SOF_PROBES_NUM_DAI_LINKS, sizeof(*links), GFP_KERNEL);
cpus = devm_kcalloc(dev, SOF_PROBES_NUM_DAI_LINKS, sizeof(*cpus), GFP_KERNEL);
if (!links || !cpus) {
Expand Down
Loading
Loading