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

Commit bc78211a authored by Tingwei Zhang's avatar Tingwei Zhang
Browse files

coresight: funnel: add support for multiple output ports



Funnel devices are now capable of supporting multiple-inputs and
multiple-outputs configuration with in built hardware filtering
for TPDM devices. Add software support to this function. Output
ports is selected according to the source of the trace path.
Add QGKI support.

Change-Id: I491293e0b1948f3747d34eb79e7845617ace4244
Signed-off-by: default avatarTingwei Zhang <tingwei@codeaurora.org>
parent a3ccff97
Loading
Loading
Loading
Loading
+13 −1
Original line number Diff line number Diff line
// SPDX-License-Identifier: GPL-2.0
/*
 * Copyright (c) 2012, The Linux Foundation. All rights reserved.
 * Copyright (c) 2012, 2019 The Linux Foundation. All rights reserved.
 */

#include <linux/acpi.h>
@@ -184,6 +184,9 @@ static int of_coresight_parse_endpoint(struct device *dev,
	struct of_endpoint endpoint, rendpoint;
	struct device_node *rparent = NULL;
	struct device_node *rep = NULL;
#ifdef CONFIG_CORESIGHT_QGKI
	struct device_node *sn = NULL;
#endif
	struct device *rdev = NULL;
	struct fwnode_handle *rdev_fwnode;

@@ -223,6 +226,15 @@ static int of_coresight_parse_endpoint(struct device *dev,
		 */
		conn->child_fwnode = fwnode_handle_get(rdev_fwnode);
		conn->child_port = rendpoint.port;
#ifdef CONFIG_CORESIGHT_QGKI
		conn->source_name = NULL;
		sn = of_parse_phandle(ep, "source", 0);
		if (sn) {
			ret = of_property_read_string(sn,
			"coresight-name", &conn->source_name);
			of_node_put(sn);
		}
#endif
		/* Connection record updated */
		ret = 1;
	} while (0);
+63 −13
Original line number Diff line number Diff line
@@ -54,6 +54,8 @@ static LIST_HEAD(cs_active_paths);
 */
const u32 barrier_pkt[4] = {0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff};

static struct coresight_device *coresight_get_source(struct list_head *path);

static int coresight_id_match(struct device *dev, void *data)
{
	int trace_id, i_trace_id;
@@ -93,6 +95,39 @@ static int coresight_source_is_unique(struct coresight_device *csdev)
				 csdev, coresight_id_match);
}

/**
 * coresight_source_filter - checks whether the connection matches the source
 * of path if connection is binded to specific source.
 * @path:	The list of devices
 * @conn:	The connection of one outport
 *
 * Return zero if the connection doesn't have a source binded or source of the
 * path matches the source binds to connection.
 */
#ifdef CONFIG_CORESIGHT_QGKI
static int coresight_source_filter(struct list_head *path,
			struct coresight_connection *conn)
{
	int ret = 0;
	struct coresight_device *source = NULL;

	if (conn->source_name == NULL)
		return ret;

	source = coresight_get_source(path);
	if (source == NULL)
		return ret;

	return strcmp(conn->source_name, dev_name(&source->dev));
}
#else
static int coresight_source_filter(struct list_head *path,
			struct coresight_connection *conn)
{
	return 0;
}
#endif

static int coresight_reset_sink(struct device *dev, void *data)
{
	struct coresight_device *csdev = to_coresight_device(dev);
@@ -111,13 +146,16 @@ static void coresight_reset_all_sink(void)
}

static int coresight_find_link_inport(struct coresight_device *csdev,
				      struct coresight_device *parent)
				      struct coresight_device *parent,
				      struct list_head *path)
{
	int i;
	struct coresight_connection *conn;

	for (i = 0; i < parent->pdata->nr_outport; i++) {
		conn = &parent->pdata->conns[i];
		if (coresight_source_filter(path, conn))
			continue;
		if (conn->child_dev == csdev)
			return conn->child_port;
	}
@@ -129,13 +167,16 @@ static int coresight_find_link_inport(struct coresight_device *csdev,
}

static int coresight_find_link_outport(struct coresight_device *csdev,
				       struct coresight_device *child)
				       struct coresight_device *child,
				       struct list_head *path)
{
	int i;
	struct coresight_connection *conn;

	for (i = 0; i < csdev->pdata->nr_outport; i++) {
		conn = &csdev->pdata->conns[i];
		if (coresight_source_filter(path, conn))
			continue;
		if (conn->child_dev == child)
			return conn->outport;
	}
@@ -268,7 +309,8 @@ static void coresight_disable_sink(struct coresight_device *csdev)

static int coresight_enable_link(struct coresight_device *csdev,
				 struct coresight_device *parent,
				 struct coresight_device *child)
				 struct coresight_device *child,
				 struct list_head *path)
{
	int ret;
	int link_subtype;
@@ -277,8 +319,8 @@ static int coresight_enable_link(struct coresight_device *csdev,
	if (!parent || !child)
		return -EINVAL;

	inport = coresight_find_link_inport(csdev, parent);
	outport = coresight_find_link_outport(csdev, child);
	inport = coresight_find_link_inport(csdev, parent, path);
	outport = coresight_find_link_outport(csdev, child, path);
	link_subtype = csdev->subtype.link_subtype;

	if (link_subtype == CORESIGHT_DEV_SUBTYPE_LINK_MERG)
@@ -308,7 +350,8 @@ static int coresight_enable_link(struct coresight_device *csdev,

static void coresight_disable_link(struct coresight_device *csdev,
				   struct coresight_device *parent,
				   struct coresight_device *child)
				   struct coresight_device *child,
				   struct list_head *path)
{
	int i, nr_conns;
	int link_subtype;
@@ -317,8 +360,8 @@ static void coresight_disable_link(struct coresight_device *csdev,
	if (!parent || !child)
		return;

	inport = coresight_find_link_inport(csdev, parent);
	outport = coresight_find_link_outport(csdev, child);
	inport = coresight_find_link_inport(csdev, parent, path);
	outport = coresight_find_link_outport(csdev, child, path);
	link_subtype = csdev->subtype.link_subtype;

	if (link_subtype == CORESIGHT_DEV_SUBTYPE_LINK_MERG) {
@@ -430,7 +473,7 @@ static void coresight_disable_path_from(struct list_head *path,
		case CORESIGHT_DEV_TYPE_LINK:
			parent = list_prev_entry(nd, link)->csdev;
			child = list_next_entry(nd, link)->csdev;
			coresight_disable_link(csdev, parent, child);
			coresight_disable_link(csdev, parent, child, path);
			break;
		default:
			break;
@@ -484,7 +527,7 @@ int coresight_enable_path(struct list_head *path, u32 mode, void *sink_data)
		case CORESIGHT_DEV_TYPE_LINK:
			parent = list_prev_entry(nd, link)->csdev;
			child = list_next_entry(nd, link)->csdev;
			ret = coresight_enable_link(csdev, parent, child);
			ret = coresight_enable_link(csdev, parent, child, path);
			if (ret)
				goto err;
			break;
@@ -667,7 +710,8 @@ static void coresight_drop_device(struct coresight_device *csdev)
 */
static int _coresight_build_path(struct coresight_device *csdev,
				 struct coresight_device *sink,
				 struct list_head *path)
				 struct list_head *path,
				 struct coresight_device *source)
{
	int i;
	bool found = false;
@@ -682,8 +726,14 @@ static int _coresight_build_path(struct coresight_device *csdev,
		struct coresight_device *child_dev;

		child_dev = csdev->pdata->conns[i].child_dev;
#ifdef CONFIG_CORESIGHT_QGKI
		if (csdev->pdata->conns[i].source_name &&
		    strcmp(csdev->pdata->conns[i].source_name,
				dev_name(&source->dev)))
			continue;
#endif
		if (child_dev &&
		    _coresight_build_path(child_dev, sink, path) == 0) {
		    _coresight_build_path(child_dev, sink, path, source) == 0) {
			found = true;
			break;
		}
@@ -725,7 +775,7 @@ struct list_head *coresight_build_path(struct coresight_device *source,

	INIT_LIST_HEAD(path);

	rc = _coresight_build_path(source, sink, path);
	rc = _coresight_build_path(source, sink, path, source);
	if (rc) {
		kfree(path);
		return ERR_PTR(rc);
+4 −0
Original line number Diff line number Diff line
@@ -127,6 +127,7 @@ struct coresight_desc {
 * struct coresight_connection - representation of a single connection
 * @outport:	a connection's output port number.
 * @child_port:	remote component's port number @output is connected to.
 * @source_name:source component's name.
 * @chid_fwnode: remote component's fwnode handle.
 * @child_dev:	a @coresight_device representation of the component
		connected to @outport.
@@ -134,6 +135,9 @@ struct coresight_desc {
struct coresight_connection {
	int outport;
	int child_port;
#ifdef CONFIG_CORESIGHT_QGKI
	const char *source_name;
#endif
	struct fwnode_handle *child_fwnode;
	struct coresight_device *child_dev;
};