Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit d5de5f3c authored by Patrick Daly's avatar Patrick Daly
Browse files

soc: qcom: remoteqdss: Implement the new communication protocol



Replace the previous format of a unique scm call id per function to
a buffer-based protocol.

CRs-Fixed: 997749
Change-Id: I7738b6369e095868fa6087aac94116f4767dc168
Signed-off-by: default avatarPatrick Daly <pdaly@codeaurora.org>
parent 241c08df
Loading
Loading
Loading
Loading
+93 −18
Original line number Diff line number Diff line
@@ -16,6 +16,7 @@
#include <soc/qcom/scm.h>
#include <linux/debugfs.h>
#include <linux/ratelimit.h>
#include <linux/dma-mapping.h>

#define REMOTEQDSS_FLAG_QUIET (BIT(0))

@@ -42,12 +43,58 @@ struct qdss_msg_translation {
 * dir			Parent debugfs directory
 */
struct remoteqdss_data {
	u8 id;
	u64 sw_entity_group;
	u64 sw_event_group;
	uint32_t id;
	uint32_t sw_entity_group;
	uint32_t sw_event_group;
	struct dentry *dir;
};

static struct device dma_dev;

/* Allowed message formats */

enum remoteqdss_cmd_id {
	CMD_ID_QUERY_SWEVENT_TAG,
	CMD_ID_FILTER_SWTRACE_STATE,
	CMD_ID_QUERY_SWTRACE_STATE,
	CMD_ID_FILTER_SWEVENT,
	CMD_ID_QUERY_SWEVENT,
	CMD_ID_FILTER_SWENTITY,
	CMD_ID_QUERY_SWENTITY,
};

struct remoteqdss_header_fmt {
	uint32_t subsys_id;
	uint32_t cmd_id;
};

struct remoteqdss_filter_swtrace_state_fmt {
	struct remoteqdss_header_fmt h;
	uint32_t state;
};

struct remoteqdss_filter_swevent_fmt {
	struct remoteqdss_header_fmt h;
	uint32_t event_group;
	uint32_t event_mask;
};

struct remoteqdss_query_swevent_fmt {
	struct remoteqdss_header_fmt h;
	uint32_t event_group;
};

struct remoteqdss_filter_swentity_fmt {
	struct remoteqdss_header_fmt h;
	uint32_t entity_group;
	uint32_t entity_mask;
};

struct remoteqdss_query_swentity_fmt {
	struct remoteqdss_header_fmt h;
	uint32_t entity_group;
};

/* msgs is a null terminated array */
static void remoteqdss_err_translation(struct qdss_msg_translation *msgs,
								u64 err)
@@ -71,9 +118,8 @@ static void remoteqdss_err_translation(struct qdss_msg_translation *msgs,
	REMOTEQDSS_ERR_CALLER("Error 0x%llx\n", err);
}

/* SCM based devices */
#define SCM_FILTER_SWTRACE_ID (0x1)
#define SCM_QUERY_SWTRACE_ID  (0x2)
/* Shared across all remoteqdss scm functions */
#define SCM_CMD_ID (0x1)

/* Response Values */
#define SCM_CMD_FAIL		(0x80)
@@ -118,20 +164,31 @@ static int remoteqdss_scm_query_swtrace(void *priv, u64 *val)
	struct remoteqdss_data *data = priv;
	int ret;
	struct scm_desc desc;
	struct remoteqdss_header_fmt *fmt;
	dma_addr_t addr;

	fmt = dma_alloc_coherent(&dma_dev, sizeof(*fmt), &addr, GFP_KERNEL);
	if (!fmt)
		return -ENOMEM;
	fmt->subsys_id = data->id;
	fmt->cmd_id = CMD_ID_QUERY_SWTRACE_STATE;

	memset(&desc, 0, sizeof(desc));
	desc.args[0] = data->id;
	desc.arginfo = SCM_ARGS(1, SCM_VAL);
	desc.args[0] = dma_to_phys(NULL, addr);
	desc.args[1] = sizeof(*fmt);
	desc.arginfo = SCM_ARGS(2, SCM_RO, SCM_VAL);

	ret = scm_call2(
		SCM_SIP_FNID(SCM_SVC_QDSS, SCM_QUERY_SWTRACE_ID),
		SCM_SIP_FNID(SCM_SVC_QDSS, SCM_CMD_ID),
		&desc);
	if (ret)
		return ret;
		goto out;

	remoteqdss_err_translation(remoteqdss_scm_msgs, desc.ret[0]);
	ret = desc.ret[0] ? -EINVAL : 0;
	*val = desc.ret[1];
out:
	dma_free_coherent(&dma_dev, sizeof(*fmt), fmt, addr);
	return ret;
}

@@ -140,26 +197,37 @@ static int remoteqdss_scm_filter_swtrace(void *priv, u64 val)
	struct remoteqdss_data *data = priv;
	int ret;
	struct scm_desc desc;
	struct remoteqdss_filter_swtrace_state_fmt *fmt;
	dma_addr_t addr;

	fmt = dma_alloc_coherent(&dma_dev, sizeof(*fmt), &addr, GFP_KERNEL);
	if (!fmt)
		return -ENOMEM;
	fmt->h.subsys_id = data->id;
	fmt->h.cmd_id = CMD_ID_FILTER_SWTRACE_STATE;
	fmt->state = (uint32_t)val;

	memset(&desc, 0, sizeof(desc));
	desc.args[0] = data->id;
	desc.args[1] = val;
	desc.args[0] = dma_to_phys(NULL, addr);
	desc.args[1] = sizeof(*fmt);
	desc.arginfo = SCM_ARGS(2, SCM_VAL, SCM_VAL);

	ret = scm_call2(
		SCM_SIP_FNID(SCM_SVC_QDSS, SCM_FILTER_SWTRACE_ID),
		SCM_SIP_FNID(SCM_SVC_QDSS, SCM_CMD_ID),
		&desc);
	if (ret)
		return ret;
		goto out;

	remoteqdss_err_translation(remoteqdss_scm_msgs, desc.ret[0]);
	ret = desc.ret[0] ? -EINVAL : 0;
out:
	dma_free_coherent(&dma_dev, sizeof(*fmt), fmt, addr);
	return ret;
}
DEFINE_SIMPLE_ATTRIBUTE(fops_sw_trace_output,
			remoteqdss_scm_query_swtrace,
			remoteqdss_scm_filter_swtrace,
			"%llu\n");
			"0x%llx\n");

static void __init enumerate_scm_devices(struct dentry *parent)
{
@@ -189,12 +257,12 @@ static void __init enumerate_scm_devices(struct dentry *parent)
	if (IS_ERR_OR_NULL(dentry))
		goto out;

	dentry = debugfs_create_u64("sw_entity_group", S_IRUGO | S_IWUSR,
	dentry = debugfs_create_u32("sw_entity_group", S_IRUGO | S_IWUSR,
			data->dir, &data->sw_entity_group);
	if (IS_ERR_OR_NULL(dentry))
		goto out;

	dentry = debugfs_create_u64("sw_event_group", S_IRUGO | S_IWUSR,
	dentry = debugfs_create_u32("sw_event_group", S_IRUGO | S_IWUSR,
			data->dir, &data->sw_event_group);
	if (IS_ERR_OR_NULL(dentry))
		goto out;
@@ -209,6 +277,13 @@ out:
static int __init remoteqdss_init(void)
{
	unsigned long old_flags = remoteqdss_dbg_flags;
	int ret;

	/* Set up DMA */
	arch_setup_dma_ops(&dma_dev, 0, U64_MAX, NULL, false);
	ret = dma_coerce_mask_and_coherent(&dma_dev, DMA_BIT_MASK(64));
	if (ret)
		return ret;

	/*
	 * disable normal error messages while checking
@@ -225,4 +300,4 @@ static int __init remoteqdss_init(void)
	remoteqdss_dbg_flags = old_flags;
	return 0;
}
module_init(remoteqdss_init);
late_initcall(remoteqdss_init);