Coresight uses DT graph bindings to describe the connections of the components. However we have some undocumented usage of the bindings to describe some of the properties of the connections.
The coresight driver needs to know the hardware ports invovled in the connection and the direction of data flow to effectively manage the trace sessions. So far we have relied on the "port" address (as described by the generic graph bindings) to represent the hardware port of the component for a connection.
The hardware uses separate numbering scheme for input and output ports, which implies, we could have two different (input and output) ports with the same port number. This could create problems in the graph bindings where the label of the port wouldn't match the address.
e.g, with the existing bindings we get :
port@0{ // Output port 0 reg = <0>; ... };
port@1{ reg = <0>; // Input port 0 endpoint { slave-mode; ... }; };
With the new enforcement in the DT rules, mismatches in label and address are not allowed (as see in the case for port@1). So, we need a new mechanism to describe the hardware port number reliably.
Also, we relied on an undocumented "slave-mode" property (see the above example) to indicate if the port is an input port. Let us formalise and switch to a new property to describe the direction of data flow.
There were three options considered for the hardware port number scheme:
1) Use natural ordering in the DT to infer the hardware port number. i.e, Mandate that the all ports are listed in the DT and in the ascending order for each class (input and output respectively). Pros : - We don't need new properties and if the existing DTS list them in order (which most of them do), they work out of the box. Cons : - We must list all the ports even if the system cannot/shouldn't use it. - It is prone to human errors (if the order is not kept).
2) Use an explicit property to list both the direction and the hw port number and direction. Define "coresight,hwid" as 2 member array of u32, where the members are port number and the direction respectively. e.g
port@0{ reg = <0>; endpoint { coresight,hwid = <0 1>; // Port # 0, Output } };
port@1{ reg = <1>; endpoint { coresight,hwid = <0 0>; // Port # 0, Input }; };
Pros: - The bindings are formal but not so reader friendly and could potentially lead to human errors. Cons: - Backward compatiblity is lost. 3) Use explicit properties (implemented in the series) for the hardware port id and direction. We define a new property "coresight,hwid" for each endpoint in coresight devices to specify the hardware port number explicitly. Also use a separate property "direction" to specify the direction of the data flow.
e.g,
port@0{ reg = <0>; endpoint { direction = <1>; // Output coresight,hwid = <0>; // Port # 0 } };
port@1{ reg = <1>; endpoint { direction = <0>; // Input coresight,hwid = <0>; // Port # 0 }; };
Pros: - The bindings are formal and reader friendly, and less prone to errors. Cons: - Backward compatibility is lost.
This series achieves implements Option (3) listed above while still retaining the backward compatibility. The driver now issues a warning (once) when it encounters the old bindings. It also cleans up the platform parsing code to reduce the memory usage by reusing the platform description. The series also includes the changes for Juno platform as an example. If there are no objections to the approach, I could post the series, converting all the in-kernel DTS to the new binding.
Suzuki K Poulose (8): dts: binding: coresight: Document graph bindings coresight: Fix remote endpoint parsing coresight: Cleanup platform description data coresight: platform: Cleanup coresight connection handling coresight: Handle errors in finding input/output ports dts: coresight: Clean up the device tree graph bindings dts: coresight: Define new bindings for direction of data flow dts: juno: Update coresight bindings for hw port
.../devicetree/bindings/arm/coresight.txt | 52 ++++++++-- arch/arm64/boot/dts/arm/juno-base.dtsi | 82 +++++++++++---- arch/arm64/boot/dts/arm/juno.dts | 5 +- drivers/hwtracing/coresight/coresight.c | 28 ++---- drivers/hwtracing/coresight/of_coresight.c | 111 ++++++++++++--------- include/linux/coresight.h | 11 +- 6 files changed, 181 insertions(+), 108 deletions(-)
Before we updat the bindings, document the current graph bindings and usage of additional properties.
Cc: Mathieu Poirier mathieu.poirier@linaro.org Signed-off-by: Suzuki K Poulose suzuki.poulose@arm.com --- .../devicetree/bindings/arm/coresight.txt | 28 ++++++++++++++++++---- 1 file changed, 24 insertions(+), 4 deletions(-)
diff --git a/Documentation/devicetree/bindings/arm/coresight.txt b/Documentation/devicetree/bindings/arm/coresight.txt index 15ac8e8..bd36e40 100644 --- a/Documentation/devicetree/bindings/arm/coresight.txt +++ b/Documentation/devicetree/bindings/arm/coresight.txt @@ -52,9 +52,7 @@ its hardware characteristcs. clocks the core of that coresight component. The latter clock is optional.
- * port or ports: The representation of the component's port - layout using the generic DT graph presentation found in - "bindings/graph.txt". + * port or ports: see "Graph bindings for Coresight" below
* Additional required properties for System Trace Macrocells (STM): * reg: along with the physical base address and length of the register @@ -71,7 +69,7 @@ its hardware characteristcs. AMBA markee): - "arm,coresight-replicator"
- * port or ports: same as above. + * port or ports: see "Graph bindings for Coresight" below.
* Optional properties for ETM/PTMs:
@@ -86,6 +84,28 @@ its hardware characteristcs. * arm,buffer-size: size of contiguous buffer space for TMC ETR (embedded trace router)
+Graph bindings for Coresight +------------------------------- + +Coresight components are interconnected to create a data path for the flow of +trace data generated from the "sources" to their collection points "sink". Each +coresight component must describe the "input" and "output" connections. +The connections must be described via generic DT graph bindings as described +by the "bindings/graph.txt", where each "port" along with an "endpoint" component +represents a hardware port and the connection. + +Since it is possible to have multiple connections for any coresight component with +a specific direction of data flow, each connection must define the following +properties to uniquely identify the connection details. + + * Direction of the data flow w.r.t the component : + Each input port must have the following property defined at the "endpoint" + for the port. + "slave-mode" + + * Hardware Port number at the component: + - The hardware port number is assumed to be the address of the "port" component. +
Example:
On Fri, Jun 01, 2018 at 02:16:00PM +0100, Suzuki K Poulose wrote:
Before we updat the bindings, document the current graph bindings
s/updat/update
and usage of additional properties.
Cc: Mathieu Poirier mathieu.poirier@linaro.org Signed-off-by: Suzuki K Poulose suzuki.poulose@arm.com
.../devicetree/bindings/arm/coresight.txt | 28 ++++++++++++++++++---- 1 file changed, 24 insertions(+), 4 deletions(-)
diff --git a/Documentation/devicetree/bindings/arm/coresight.txt b/Documentation/devicetree/bindings/arm/coresight.txt index 15ac8e8..bd36e40 100644 --- a/Documentation/devicetree/bindings/arm/coresight.txt +++ b/Documentation/devicetree/bindings/arm/coresight.txt @@ -52,9 +52,7 @@ its hardware characteristcs. clocks the core of that coresight component. The latter clock is optional.
- port or ports: The representation of the component's port
layout using the generic DT graph presentation found in
"bindings/graph.txt".
- port or ports: see "Graph bindings for Coresight" below
- Additional required properties for System Trace Macrocells (STM):
- reg: along with the physical base address and length of the register
@@ -71,7 +69,7 @@ its hardware characteristcs. AMBA markee): - "arm,coresight-replicator"
- port or ports: same as above.
- port or ports: see "Graph bindings for Coresight" below.
- Optional properties for ETM/PTMs:
@@ -86,6 +84,28 @@ its hardware characteristcs.
- arm,buffer-size: size of contiguous buffer space for TMC ETR
(embedded trace router)
+Graph bindings for Coresight +-------------------------------
+Coresight components are interconnected to create a data path for the flow of +trace data generated from the "sources" to their collection points "sink". Each
Over 80 characters.
+coresight component must describe the "input" and "output" connections. +The connections must be described via generic DT graph bindings as described +by the "bindings/graph.txt", where each "port" along with an "endpoint" component
Same here.
+represents a hardware port and the connection.
+Since it is possible to have multiple connections for any coresight component with
And here.
+a specific direction of data flow, each connection must define the following +properties to uniquely identify the connection details.
- Direction of the data flow w.r.t the component :
- Each input port must have the following property defined at the "endpoint"
- for the port.
- "slave-mode"
- Hardware Port number at the component:
- The hardware port number is assumed to be the address of the "port" component.
And here.
Moveover this patches doesn't apply to my next tree.
Example: -- 2.7.4
When parsing the remote endpoint of an output port, we do : rport = of_graph_get_remote_port(ep); rparent = of_graph_get_remote_port_parent(ep);
and then parse the "remote_port" as if it was the remote endpoint, which is wrong. The code worked fine because we used endpoint number as the port number. Let us fix it and optimise a bit as:
remote_ep = of_graph_get_remote_endpoint(ep); if (remote_ep) remote_parent = of_graph_get_port_parent(remote_ep);
and then, parse the remote_ep for the port/endpoint details.
Cc: Mathieu Poirier mathieu.poirier@linaro.org Signed-off-by: Suzuki K Poulose suzuki.poulose@arm.com --- drivers/hwtracing/coresight/of_coresight.c | 19 ++++++++++--------- 1 file changed, 10 insertions(+), 9 deletions(-)
diff --git a/drivers/hwtracing/coresight/of_coresight.c b/drivers/hwtracing/coresight/of_coresight.c index 7c37544..e0deab0 100644 --- a/drivers/hwtracing/coresight/of_coresight.c +++ b/drivers/hwtracing/coresight/of_coresight.c @@ -128,7 +128,7 @@ of_get_coresight_platform_data(struct device *dev, struct device *rdev; struct device_node *ep = NULL; struct device_node *rparent = NULL; - struct device_node *rport = NULL; + struct device_node *rep = NULL;
pdata = devm_kzalloc(dev, sizeof(*pdata), GFP_KERNEL); if (!pdata) @@ -169,16 +169,17 @@ of_get_coresight_platform_data(struct device *dev, pdata->outports[i] = endpoint.port;
/* - * Get a handle on the remote port and parent - * attached to it. + * Get a handle on the remote endpoint and the device + * it is attached to. */ - rparent = of_graph_get_remote_port_parent(ep); - rport = of_graph_get_remote_port(ep); - - if (!rparent || !rport) + rep = of_graph_get_remote_endpoint(ep); + if (!rep) + continue; + rparent = of_graph_get_port_parent(rep); + if (!rparent) continue;
- if (of_graph_parse_endpoint(rport, &rendpoint)) + if (of_graph_parse_endpoint(rep, &rendpoint)) continue;
rdev = of_coresight_get_endpoint_device(rparent); @@ -186,7 +187,7 @@ of_get_coresight_platform_data(struct device *dev, return ERR_PTR(-EPROBE_DEFER);
pdata->child_names[i] = dev_name(rdev); - pdata->child_ports[i] = rendpoint.id; + pdata->child_ports[i] = rendpoint.port;
i++; } while (ep);
On Fri, Jun 01, 2018 at 02:16:01PM +0100, Suzuki K Poulose wrote:
When parsing the remote endpoint of an output port, we do : rport = of_graph_get_remote_port(ep); rparent = of_graph_get_remote_port_parent(ep);
and then parse the "remote_port" as if it was the remote endpoint, which is wrong. The code worked fine because we used endpoint number as the port number. Let us fix it and optimise a bit as:
remote_ep = of_graph_get_remote_endpoint(ep); if (remote_ep) remote_parent = of_graph_get_port_parent(remote_ep);
and then, parse the remote_ep for the port/endpoint details.
Cc: Mathieu Poirier mathieu.poirier@linaro.org Signed-off-by: Suzuki K Poulose suzuki.poulose@arm.com
drivers/hwtracing/coresight/of_coresight.c | 19 ++++++++++--------- 1 file changed, 10 insertions(+), 9 deletions(-)
diff --git a/drivers/hwtracing/coresight/of_coresight.c b/drivers/hwtracing/coresight/of_coresight.c index 7c37544..e0deab0 100644 --- a/drivers/hwtracing/coresight/of_coresight.c +++ b/drivers/hwtracing/coresight/of_coresight.c @@ -128,7 +128,7 @@ of_get_coresight_platform_data(struct device *dev, struct device *rdev; struct device_node *ep = NULL; struct device_node *rparent = NULL;
- struct device_node *rport = NULL;
- struct device_node *rep = NULL;
pdata = devm_kzalloc(dev, sizeof(*pdata), GFP_KERNEL); if (!pdata) @@ -169,16 +169,17 @@ of_get_coresight_platform_data(struct device *dev, pdata->outports[i] = endpoint.port; /*
* Get a handle on the remote port and parent
* attached to it.
* Get a handle on the remote endpoint and the device
* it is attached to. */
rparent = of_graph_get_remote_port_parent(ep);
rport = of_graph_get_remote_port(ep);
if (!rparent || !rport)
rep = of_graph_get_remote_endpoint(ep);
if (!rep)
continue;
rparent = of_graph_get_port_parent(rep);
if (!rparent) continue;
if (of_graph_parse_endpoint(rport, &rendpoint))
if (of_graph_parse_endpoint(rep, &rendpoint)) continue;
You are correct and I'm out to lunch.
rdev = of_coresight_get_endpoint_device(rparent); @@ -186,7 +187,7 @@ of_get_coresight_platform_data(struct device *dev, return ERR_PTR(-EPROBE_DEFER); pdata->child_names[i] = dev_name(rdev);
pdata->child_ports[i] = rendpoint.id;
pdata->child_ports[i] = rendpoint.port;
You need to do a of_node_put() here for both rep and rparent.
i++; } while (ep); -- 2.7.4
On 1 June 2018 at 13:38, Mathieu Poirier mathieu.poirier@linaro.org wrote:
On Fri, Jun 01, 2018 at 02:16:01PM +0100, Suzuki K Poulose wrote:
When parsing the remote endpoint of an output port, we do : rport = of_graph_get_remote_port(ep); rparent = of_graph_get_remote_port_parent(ep);
and then parse the "remote_port" as if it was the remote endpoint, which is wrong. The code worked fine because we used endpoint number as the port number. Let us fix it and optimise a bit as:
remote_ep = of_graph_get_remote_endpoint(ep); if (remote_ep) remote_parent = of_graph_get_port_parent(remote_ep);
and then, parse the remote_ep for the port/endpoint details.
Cc: Mathieu Poirier mathieu.poirier@linaro.org Signed-off-by: Suzuki K Poulose suzuki.poulose@arm.com
drivers/hwtracing/coresight/of_coresight.c | 19 ++++++++++--------- 1 file changed, 10 insertions(+), 9 deletions(-)
diff --git a/drivers/hwtracing/coresight/of_coresight.c b/drivers/hwtracing/coresight/of_coresight.c index 7c37544..e0deab0 100644 --- a/drivers/hwtracing/coresight/of_coresight.c +++ b/drivers/hwtracing/coresight/of_coresight.c @@ -128,7 +128,7 @@ of_get_coresight_platform_data(struct device *dev, struct device *rdev; struct device_node *ep = NULL; struct device_node *rparent = NULL;
struct device_node *rport = NULL;
struct device_node *rep = NULL; pdata = devm_kzalloc(dev, sizeof(*pdata), GFP_KERNEL); if (!pdata)
@@ -169,16 +169,17 @@ of_get_coresight_platform_data(struct device *dev, pdata->outports[i] = endpoint.port;
/*
* Get a handle on the remote port and parent
* attached to it.
* Get a handle on the remote endpoint and the device
* it is attached to. */
rparent = of_graph_get_remote_port_parent(ep);
rport = of_graph_get_remote_port(ep);
if (!rparent || !rport)
rep = of_graph_get_remote_endpoint(ep);
if (!rep)
continue;
rparent = of_graph_get_port_parent(rep);
if (!rparent) continue;
if (of_graph_parse_endpoint(rport, &rendpoint))
if (of_graph_parse_endpoint(rep, &rendpoint)) continue;
You are correct and I'm out to lunch.
rdev = of_coresight_get_endpoint_device(rparent);
@@ -186,7 +187,7 @@ of_get_coresight_platform_data(struct device *dev, return ERR_PTR(-EPROBE_DEFER);
pdata->child_names[i] = dev_name(rdev);
pdata->child_ports[i] = rendpoint.id;
pdata->child_ports[i] = rendpoint.port;
You need to do a of_node_put() here for both rep and rparent.
Same thing for the "continue" and error condition above.
i++; } while (ep);
-- 2.7.4
On 06/01/2018 08:46 PM, Mathieu Poirier wrote:
On 1 June 2018 at 13:38, Mathieu Poirier mathieu.poirier@linaro.org wrote:
On Fri, Jun 01, 2018 at 02:16:01PM +0100, Suzuki K Poulose wrote:
When parsing the remote endpoint of an output port, we do : rport = of_graph_get_remote_port(ep); rparent = of_graph_get_remote_port_parent(ep);
and then parse the "remote_port" as if it was the remote endpoint, which is wrong. The code worked fine because we used endpoint number as the port number. Let us fix it and optimise a bit as:
remote_ep = of_graph_get_remote_endpoint(ep); if (remote_ep) remote_parent = of_graph_get_port_parent(remote_ep);
and then, parse the remote_ep for the port/endpoint details.
Cc: Mathieu Poirier mathieu.poirier@linaro.org Signed-off-by: Suzuki K Poulose suzuki.poulose@arm.com
drivers/hwtracing/coresight/of_coresight.c | 19 ++++++++++--------- 1 file changed, 10 insertions(+), 9 deletions(-)
diff --git a/drivers/hwtracing/coresight/of_coresight.c b/drivers/hwtracing/coresight/of_coresight.c index 7c37544..e0deab0 100644 --- a/drivers/hwtracing/coresight/of_coresight.c +++ b/drivers/hwtracing/coresight/of_coresight.c @@ -128,7 +128,7 @@ of_get_coresight_platform_data(struct device *dev, struct device *rdev; struct device_node *ep = NULL; struct device_node *rparent = NULL;
struct device_node *rport = NULL;
struct device_node *rep = NULL; pdata = devm_kzalloc(dev, sizeof(*pdata), GFP_KERNEL); if (!pdata)
@@ -169,16 +169,17 @@ of_get_coresight_platform_data(struct device *dev, pdata->outports[i] = endpoint.port;
/*
* Get a handle on the remote port and parent
* attached to it.
* Get a handle on the remote endpoint and the device
* it is attached to. */
rparent = of_graph_get_remote_port_parent(ep);
rport = of_graph_get_remote_port(ep);
if (!rparent || !rport)
rep = of_graph_get_remote_endpoint(ep);
if (!rep)
continue;
rparent = of_graph_get_port_parent(rep);
if (!rparent) continue;
if (of_graph_parse_endpoint(rport, &rendpoint))
if (of_graph_parse_endpoint(rep, &rendpoint)) continue;
You are correct and I'm out to lunch.
rdev = of_coresight_get_endpoint_device(rparent);
@@ -186,7 +187,7 @@ of_get_coresight_platform_data(struct device *dev, return ERR_PTR(-EPROBE_DEFER);
pdata->child_names[i] = dev_name(rdev);
pdata->child_ports[i] = rendpoint.id;
pdata->child_ports[i] = rendpoint.port;
You need to do a of_node_put() here for both rep and rparent.
Same thing for the "continue" and error condition above.
Mathieu,
Thanks for pointing that out. I see that we were missing them for the existing code as well. I will clean all this up.
Cheers Suzuki
Nobody uses the "clk" field in struct coresight_platform_data. Remove it.
Cc: Mathieu Poirier mathieu.poirier@linaro.org Signed-off-by: Suzuki K Poulose suzuki.poulose@arm.com --- include/linux/coresight.h | 2 -- 1 file changed, 2 deletions(-)
diff --git a/include/linux/coresight.h b/include/linux/coresight.h index d950dad..32aaa1c 100644 --- a/include/linux/coresight.h +++ b/include/linux/coresight.h @@ -94,7 +94,6 @@ struct coresight_dev_subtype { * @child_ports:child component port number the current component is connected to. * @nr_outport: number of output ports for this component. - * @clk: The clock this component is associated to. */ struct coresight_platform_data { int cpu; @@ -104,7 +103,6 @@ struct coresight_platform_data { const char **child_names; int *child_ports; int nr_outport; - struct clk *clk; };
/**
The platform code parses the component connections and populates a platform-description of the output connections in arrays of fields (which is never freed). This is later copied in the coresight_register to a newly allocated area, represented by coresight_connection(s).
This patch cleans up the code dealing with connections by making use of the "coresight_connection" structure right at the platform code and lets the generic driver simply re-use information provided by the platform.
Thus making it reader friendly as well as avoiding the wastage of unused memory.
Cc: Mathieu Poirier mathieu.poirier@linaro.org Signed-off-by: Suzuki K Poulose suzuki.poulose@arm.com --- drivers/hwtracing/coresight/coresight.c | 21 +--------------- drivers/hwtracing/coresight/of_coresight.c | 40 +++++++++++------------------- include/linux/coresight.h | 9 ++----- 3 files changed, 17 insertions(+), 53 deletions(-)
diff --git a/drivers/hwtracing/coresight/coresight.c b/drivers/hwtracing/coresight/coresight.c index 389c4ba..3b3756e 100644 --- a/drivers/hwtracing/coresight/coresight.c +++ b/drivers/hwtracing/coresight/coresight.c @@ -961,13 +961,11 @@ postcore_initcall(coresight_init);
struct coresight_device *coresight_register(struct coresight_desc *desc) { - int i; int ret; int link_subtype; int nr_refcnts = 1; atomic_t *refcnts = NULL; struct coresight_device *csdev; - struct coresight_connection *conns = NULL;
csdev = kzalloc(sizeof(*csdev), GFP_KERNEL); if (!csdev) { @@ -996,22 +994,7 @@ struct coresight_device *coresight_register(struct coresight_desc *desc) csdev->nr_inport = desc->pdata->nr_inport; csdev->nr_outport = desc->pdata->nr_outport;
- /* Initialise connections if there is at least one outport */ - if (csdev->nr_outport) { - conns = kcalloc(csdev->nr_outport, sizeof(*conns), GFP_KERNEL); - if (!conns) { - ret = -ENOMEM; - goto err_kzalloc_conns; - } - - for (i = 0; i < csdev->nr_outport; i++) { - conns[i].outport = desc->pdata->outports[i]; - conns[i].child_name = desc->pdata->child_names[i]; - conns[i].child_port = desc->pdata->child_ports[i]; - } - } - - csdev->conns = conns; + csdev->conns = desc->pdata->conns;
csdev->type = desc->type; csdev->subtype = desc->subtype; @@ -1039,8 +1022,6 @@ struct coresight_device *coresight_register(struct coresight_desc *desc) return csdev;
err_device_register: - kfree(conns); -err_kzalloc_conns: kfree(refcnts); err_kzalloc_refcnts: kfree(csdev); diff --git a/drivers/hwtracing/coresight/of_coresight.c b/drivers/hwtracing/coresight/of_coresight.c index e0deab0..a3f3416 100644 --- a/drivers/hwtracing/coresight/of_coresight.c +++ b/drivers/hwtracing/coresight/of_coresight.c @@ -77,26 +77,13 @@ static void of_coresight_get_ports(const struct device_node *node, static int of_coresight_alloc_memory(struct device *dev, struct coresight_platform_data *pdata) { - /* List of output port on this component */ - pdata->outports = devm_kzalloc(dev, pdata->nr_outport * - sizeof(*pdata->outports), - GFP_KERNEL); - if (!pdata->outports) - return -ENOMEM; - - /* Children connected to this component via @outports */ - pdata->child_names = devm_kzalloc(dev, pdata->nr_outport * - sizeof(*pdata->child_names), - GFP_KERNEL); - if (!pdata->child_names) - return -ENOMEM; - - /* Port number on the child this component is connected to */ - pdata->child_ports = devm_kzalloc(dev, pdata->nr_outport * - sizeof(*pdata->child_ports), - GFP_KERNEL); - if (!pdata->child_ports) - return -ENOMEM; + if (pdata->nr_outport) { + pdata->conns = devm_kzalloc(dev, pdata->nr_outport * + sizeof(*pdata->conns), + GFP_KERNEL); + if (!pdata->conns) + return -ENOMEM; + }
return 0; } @@ -122,8 +109,9 @@ struct coresight_platform_data * of_get_coresight_platform_data(struct device *dev, const struct device_node *node) { - int i = 0, ret = 0; + int ret = 0; struct coresight_platform_data *pdata; + struct coresight_connection *conn; struct of_endpoint endpoint, rendpoint; struct device *rdev; struct device_node *ep = NULL; @@ -145,6 +133,7 @@ of_get_coresight_platform_data(struct device *dev, if (ret) return ERR_PTR(ret);
+ conn = pdata->conns; /* Iterate through each port to discover topology */ do { /* Get a handle on a port */ @@ -166,7 +155,7 @@ of_get_coresight_platform_data(struct device *dev, continue;
/* The local out port number */ - pdata->outports[i] = endpoint.port; + conn->outport = endpoint.port;
/* * Get a handle on the remote endpoint and the device @@ -186,10 +175,9 @@ of_get_coresight_platform_data(struct device *dev, if (!rdev) return ERR_PTR(-EPROBE_DEFER);
- pdata->child_names[i] = dev_name(rdev); - pdata->child_ports[i] = rendpoint.port; - - i++; + conn->child_name = dev_name(rdev); + conn->child_port = rendpoint.port; + conn++; } while (ep); }
diff --git a/include/linux/coresight.h b/include/linux/coresight.h index 32aaa1c..c2363bb 100644 --- a/include/linux/coresight.h +++ b/include/linux/coresight.h @@ -89,20 +89,15 @@ struct coresight_dev_subtype { * @cpu: the CPU a source belongs to. Only applicable for ETM/PTMs. * @name: name of the component as shown under sysfs. * @nr_inport: number of input ports for this component. - * @outports: list of remote endpoint port number. - * @child_names:name of all child components connected to this device. - * @child_ports:child component port number the current component is - connected to. * @nr_outport: number of output ports for this component. + * @conns: Array of nr_outport connections from this component */ struct coresight_platform_data { int cpu; const char *name; int nr_inport; - int *outports; - const char **child_names; - int *child_ports; int nr_outport; + struct coresight_connection *conns; };
/**
If we fail to find the input / output port for a LINK component while enabling a path, we should fail gracefully rather than assuming port "0".
Cc: Mathieu Poirier mathieu.poirier@linaro.org Signed-off-by: Suzuki K Poulose suzuki.poulose@arm.com --- drivers/hwtracing/coresight/coresight.c | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-)
diff --git a/drivers/hwtracing/coresight/coresight.c b/drivers/hwtracing/coresight/coresight.c index 3b3756e..4dcea6e 100644 --- a/drivers/hwtracing/coresight/coresight.c +++ b/drivers/hwtracing/coresight/coresight.c @@ -115,7 +115,7 @@ static int coresight_find_link_inport(struct coresight_device *csdev, dev_err(&csdev->dev, "couldn't find inport, parent: %s, child: %s\n", dev_name(&parent->dev), dev_name(&csdev->dev));
- return 0; + return -ENODEV; }
static int coresight_find_link_outport(struct coresight_device *csdev, @@ -133,7 +133,7 @@ static int coresight_find_link_outport(struct coresight_device *csdev, dev_err(&csdev->dev, "couldn't find outport, parent: %s, child: %s\n", dev_name(&csdev->dev), dev_name(&child->dev));
- return 0; + return -ENODEV; }
static int coresight_enable_sink(struct coresight_device *csdev, u32 mode) @@ -186,6 +186,9 @@ static int coresight_enable_link(struct coresight_device *csdev, else refport = 0;
+ if (refport < 0) + return refport; + if (atomic_inc_return(&csdev->refcnt[refport]) == 1) { if (link_ops(csdev)->enable) { ret = link_ops(csdev)->enable(csdev, inport, outport);
The coresight drivers relied on default bindings for graph in DT, while reusing the "reg" field of the "ports" to indicate the actual hardware port number for the connections. However, with the rules getting stricter w.r.t to the address mismatch with the label, it is no longer possible to use the port address field for the hardware port number. Hence, we add an explicit property to denote the hardware port number, "coresight,hwid" which must be specified for each "endpoint".
Cc: Mathieu Poirier mathieu.poirier@linaro.org Cc: Sudeep Holla sudeep.holla@arm.com Cc: Rob Herring robh@kernel.org Signed-off-by: Suzuki K Poulose suzuki.poulose@arm.com --- .../devicetree/bindings/arm/coresight.txt | 26 +++++++++--- drivers/hwtracing/coresight/of_coresight.c | 46 ++++++++++++++++------ 2 files changed, 54 insertions(+), 18 deletions(-)
diff --git a/Documentation/devicetree/bindings/arm/coresight.txt b/Documentation/devicetree/bindings/arm/coresight.txt index bd36e40..385581a 100644 --- a/Documentation/devicetree/bindings/arm/coresight.txt +++ b/Documentation/devicetree/bindings/arm/coresight.txt @@ -104,7 +104,11 @@ properties to uniquely identify the connection details. "slave-mode"
* Hardware Port number at the component: - - The hardware port number is assumed to be the address of the "port" component. + - (Obsolete) The hardware port number is assumed to be the address of the "port" component. + - Each "endpoint" must define the hardware port of the local end of the + connection using the following property: + "coresight,hwid" - 32bit integer, hardware port number at the local end. +
Example: @@ -120,6 +124,7 @@ Example: etb_in_port: endpoint@0 { slave-mode; remote-endpoint = <&replicator_out_port0>; + coresight,hwid = <0>; }; }; }; @@ -134,6 +139,7 @@ Example: tpiu_in_port: endpoint@0 { slave-mode; remote-endpoint = <&replicator_out_port1>; + coresight,hwid = <0>; }; }; }; @@ -154,6 +160,7 @@ Example: reg = <0>; replicator_out_port0: endpoint { remote-endpoint = <&etb_in_port>; + coresight,hwid = <0>; }; };
@@ -161,15 +168,17 @@ Example: reg = <1>; replicator_out_port1: endpoint { remote-endpoint = <&tpiu_in_port>; + coresight,hwid = <1>; }; };
/* replicator input port */ port@2 { - reg = <0>; + reg = <1>; replicator_in_port0: endpoint { slave-mode; remote-endpoint = <&funnel_out_port0>; + coresight,hwid = <0>; }; }; }; @@ -191,31 +200,35 @@ Example: funnel_out_port0: endpoint { remote-endpoint = <&replicator_in_port0>; + coresight,hwid = <0>; }; };
/* funnel input ports */ port@1 { - reg = <0>; + reg = <1>; funnel_in_port0: endpoint { slave-mode; remote-endpoint = <&ptm0_out_port>; + coresight,hwid = <0>; }; };
port@2 { - reg = <1>; + reg = <2>; funnel_in_port1: endpoint { slave-mode; remote-endpoint = <&ptm1_out_port>; + coresight,hwid = <1>; }; };
port@3 { - reg = <2>; + reg = <3>; funnel_in_port2: endpoint { slave-mode; remote-endpoint = <&etm0_out_port>; + coresight,hwid = <2>; }; };
@@ -233,6 +246,7 @@ Example: port { ptm0_out_port: endpoint { remote-endpoint = <&funnel_in_port0>; + coresight,hwid = <0>; }; }; }; @@ -247,6 +261,7 @@ Example: port { ptm1_out_port: endpoint { remote-endpoint = <&funnel_in_port1>; + coresight,hwid = <0>; }; }; }; @@ -263,6 +278,7 @@ Example: port { stm_out_port: endpoint { remote-endpoint = <&main_funnel_in_port2>; + coresight,hwid = <0>; }; }; }; diff --git a/drivers/hwtracing/coresight/of_coresight.c b/drivers/hwtracing/coresight/of_coresight.c index a3f3416..99d7a9c 100644 --- a/drivers/hwtracing/coresight/of_coresight.c +++ b/drivers/hwtracing/coresight/of_coresight.c @@ -105,14 +105,37 @@ int of_coresight_get_cpu(const struct device_node *node) } EXPORT_SYMBOL_GPL(of_coresight_get_cpu);
+/* + * of_graph_ep_coresight_get_port_id : Get the hardware port number for the + * given endpoint device node. Prefer the explicit "coresight,hwid" property + * over the endpoint register id (obsolete bindings). + */ +static int of_graph_ep_coresight_get_port_id(struct device *dev, + struct device_node *ep_node) +{ + struct of_endpoint ep; + int rc, port_id; + + + if (!of_property_read_u32(ep_node, "coresight,hwid", &port_id)) + return port_id; + + rc = of_graph_parse_endpoint(ep_node, &ep); + if (rc) + return rc; + dev_warn_once(dev, + "ep%d: Mandatory "coresight,hwid" property missing." + " DT uses obsolete coresight bindings\n", ep.port); + return ep.port; +} + struct coresight_platform_data * of_get_coresight_platform_data(struct device *dev, const struct device_node *node) { - int ret = 0; + int ret = 0, outport, inport; struct coresight_platform_data *pdata; struct coresight_connection *conn; - struct of_endpoint endpoint, rendpoint; struct device *rdev; struct device_node *ep = NULL; struct device_node *rparent = NULL; @@ -148,14 +171,10 @@ of_get_coresight_platform_data(struct device *dev, if (of_find_property(ep, "slave-mode", NULL)) continue;
- /* Get a handle on the local endpoint */ - ret = of_graph_parse_endpoint(ep, &endpoint); - - if (ret) + outport = of_graph_ep_coresight_get_port_id(dev, ep); + if (outport < 0) continue; - - /* The local out port number */ - conn->outport = endpoint.port; + conn->outport = outport;
/* * Get a handle on the remote endpoint and the device @@ -168,15 +187,16 @@ of_get_coresight_platform_data(struct device *dev, if (!rparent) continue;
- if (of_graph_parse_endpoint(rep, &rendpoint)) - continue; - rdev = of_coresight_get_endpoint_device(rparent); if (!rdev) return ERR_PTR(-EPROBE_DEFER);
+ inport = of_graph_ep_coresight_get_port_id(rdev, rep); + if (inport < 0) + continue; + conn->child_name = dev_name(rdev); - conn->child_port = rendpoint.port; + conn->child_port = inport; conn++; } while (ep); }
On Fri, Jun 01, 2018 at 02:16:05PM +0100, Suzuki K Poulose wrote:
The coresight drivers relied on default bindings for graph in DT, while reusing the "reg" field of the "ports" to indicate the actual hardware port number for the connections. However, with the rules getting stricter w.r.t to the address mismatch with the label, it is no longer possible to use the port address field for the hardware port number. Hence, we add an explicit property to denote the hardware port number, "coresight,hwid" which must be specified for each "endpoint".
Cc: Mathieu Poirier mathieu.poirier@linaro.org Cc: Sudeep Holla sudeep.holla@arm.com Cc: Rob Herring robh@kernel.org Signed-off-by: Suzuki K Poulose suzuki.poulose@arm.com
.../devicetree/bindings/arm/coresight.txt | 26 +++++++++--- drivers/hwtracing/coresight/of_coresight.c | 46 ++++++++++++++++------ 2 files changed, 54 insertions(+), 18 deletions(-)
diff --git a/Documentation/devicetree/bindings/arm/coresight.txt b/Documentation/devicetree/bindings/arm/coresight.txt index bd36e40..385581a 100644 --- a/Documentation/devicetree/bindings/arm/coresight.txt +++ b/Documentation/devicetree/bindings/arm/coresight.txt @@ -104,7 +104,11 @@ properties to uniquely identify the connection details. "slave-mode"
- Hardware Port number at the component:
- The hardware port number is assumed to be the address of the "port" component.
- (Obsolete) The hardware port number is assumed to be the address of the "port" component.
- Each "endpoint" must define the hardware port of the local end of the
connection using the following property:
- "coresight,hwid" - 32bit integer, hardware port number at the local end.
Example: @@ -120,6 +124,7 @@ Example: etb_in_port: endpoint@0 { slave-mode; remote-endpoint = <&replicator_out_port0>;
}; };coresight,hwid = <0>; };
@@ -134,6 +139,7 @@ Example: tpiu_in_port: endpoint@0 { slave-mode; remote-endpoint = <&replicator_out_port1>;
}; };coresight,hwid = <0>; };
@@ -154,6 +160,7 @@ Example: reg = <0>; replicator_out_port0: endpoint { remote-endpoint = <&etb_in_port>;
coresight,hwid = <0>; }; };
@@ -161,15 +168,17 @@ Example: reg = <1>; replicator_out_port1: endpoint { remote-endpoint = <&tpiu_in_port>;
coresight,hwid = <1>; }; };
/* replicator input port */ port@2 {
reg = <0>;
reg = <1>; replicator_in_port0: endpoint { slave-mode; remote-endpoint = <&funnel_out_port0>;
};coresight,hwid = <0>; }; };
@@ -191,31 +200,35 @@ Example: funnel_out_port0: endpoint { remote-endpoint = <&replicator_in_port0>;
coresight,hwid = <0>; }; };
/* funnel input ports */ port@1 {
reg = <0>;
reg = <1>; funnel_in_port0: endpoint { slave-mode; remote-endpoint = <&ptm0_out_port>;
coresight,hwid = <0>; }; };
port@2 {
reg = <1>;
reg = <2>; funnel_in_port1: endpoint { slave-mode; remote-endpoint = <&ptm1_out_port>;
coresight,hwid = <1>; }; };
port@3 {
reg = <2>;
reg = <3>; funnel_in_port2: endpoint { slave-mode; remote-endpoint = <&etm0_out_port>;
coresight,hwid = <2>; }; };
@@ -233,6 +246,7 @@ Example: port { ptm0_out_port: endpoint { remote-endpoint = <&funnel_in_port0>;
}; };coresight,hwid = <0>; };
@@ -247,6 +261,7 @@ Example: port { ptm1_out_port: endpoint { remote-endpoint = <&funnel_in_port1>;
}; };coresight,hwid = <0>; };
@@ -263,6 +278,7 @@ Example: port { stm_out_port: endpoint { remote-endpoint = <&main_funnel_in_port2>;
}; };coresight,hwid = <0>; };
diff --git a/drivers/hwtracing/coresight/of_coresight.c b/drivers/hwtracing/coresight/of_coresight.c index a3f3416..99d7a9c 100644 --- a/drivers/hwtracing/coresight/of_coresight.c +++ b/drivers/hwtracing/coresight/of_coresight.c @@ -105,14 +105,37 @@ int of_coresight_get_cpu(const struct device_node *node) } EXPORT_SYMBOL_GPL(of_coresight_get_cpu); +/*
- of_graph_ep_coresight_get_port_id : Get the hardware port number for the
- given endpoint device node. Prefer the explicit "coresight,hwid" property
- over the endpoint register id (obsolete bindings).
- */
+static int of_graph_ep_coresight_get_port_id(struct device *dev,
struct device_node *ep_node)
static int of_coresight_endpoint_get_port_id(struct device *dev, struct device_node *ep_node)
I think that makes more sense since this function is only visible in this file.
+{
- struct of_endpoint ep;
- int rc, port_id;
- if (!of_property_read_u32(ep_node, "coresight,hwid", &port_id))
return port_id;
- rc = of_graph_parse_endpoint(ep_node, &ep);
- if (rc)
return rc;
- dev_warn_once(dev,
"ep%d: Mandatory \"coresight,hwid\" property missing."
" DT uses obsolete coresight bindings\n", ep.port);
- return ep.port;
+}
struct coresight_platform_data * of_get_coresight_platform_data(struct device *dev, const struct device_node *node) {
- int ret = 0;
- int ret = 0, outport, inport; struct coresight_platform_data *pdata; struct coresight_connection *conn;
- struct of_endpoint endpoint, rendpoint; struct device *rdev; struct device_node *ep = NULL; struct device_node *rparent = NULL;
@@ -148,14 +171,10 @@ of_get_coresight_platform_data(struct device *dev, if (of_find_property(ep, "slave-mode", NULL)) continue;
/* Get a handle on the local endpoint */
ret = of_graph_parse_endpoint(ep, &endpoint);
if (ret)
outport = of_graph_ep_coresight_get_port_id(dev, ep);
if (outport < 0) continue;
/* The local out port number */
conn->outport = endpoint.port;
conn->outport = outport;
/* * Get a handle on the remote endpoint and the device @@ -168,15 +187,16 @@ of_get_coresight_platform_data(struct device *dev, if (!rparent) continue;
if (of_graph_parse_endpoint(rep, &rendpoint))
continue;
rdev = of_coresight_get_endpoint_device(rparent); if (!rdev) return ERR_PTR(-EPROBE_DEFER);
inport = of_graph_ep_coresight_get_port_id(rdev, rep);
if (inport < 0)
continue;
conn->child_name = dev_name(rdev);
conn->child_port = rendpoint.port;
} while (ep); }conn->child_port = inport; conn++;
-- 2.7.4
On Fri, Jun 01, 2018 at 02:16:05PM +0100, Suzuki K Poulose wrote:
The coresight drivers relied on default bindings for graph in DT, while reusing the "reg" field of the "ports" to indicate the actual hardware port number for the connections. However, with the rules getting stricter w.r.t to the address mismatch with the label, it is no longer possible to use the port address field for the hardware port number. Hence, we add an explicit property to denote the hardware port number, "coresight,hwid" which must be specified for each "endpoint".
Cc: Mathieu Poirier mathieu.poirier@linaro.org Cc: Sudeep Holla sudeep.holla@arm.com Cc: Rob Herring robh@kernel.org Signed-off-by: Suzuki K Poulose suzuki.poulose@arm.com
.../devicetree/bindings/arm/coresight.txt | 26 +++++++++--- drivers/hwtracing/coresight/of_coresight.c | 46 ++++++++++++++++------ 2 files changed, 54 insertions(+), 18 deletions(-)
diff --git a/Documentation/devicetree/bindings/arm/coresight.txt b/Documentation/devicetree/bindings/arm/coresight.txt index bd36e40..385581a 100644 --- a/Documentation/devicetree/bindings/arm/coresight.txt +++ b/Documentation/devicetree/bindings/arm/coresight.txt @@ -104,7 +104,11 @@ properties to uniquely identify the connection details. "slave-mode"
- Hardware Port number at the component:
- The hardware port number is assumed to be the address of the "port" component.
- (Obsolete) The hardware port number is assumed to be the address of the "port" component.
- Each "endpoint" must define the hardware port of the local end of the
connection using the following property:
- "coresight,hwid" - 32bit integer, hardware port number at the local end.
"coresight" is not a vendor and properties are in the form [<vendor>,]<prop-name>.
Example: @@ -120,6 +124,7 @@ Example: etb_in_port: endpoint@0 {
There shouldn't be a unit address here because there is no reg property.
slave-mode; remote-endpoint = <&replicator_out_port0>;
coresight,hwid = <0>;
It doesn't make sense for these to be in the endpoint. If you had multiple endpoints, then you would have to duplicate it. "ports" are a single data stream. "endpoints" are connections to that stream. So if you have a muxed (input) or fanout/1-to-many (output) connection, then you have multiple endpoints.
The same applied to the slave-mode property, but that ship has sailed. No reason to continue that though.
}; };
}; @@ -134,6 +139,7 @@ Example: tpiu_in_port: endpoint@0 { slave-mode; remote-endpoint = <&replicator_out_port1>;
}; };coresight,hwid = <0>; };
@@ -154,6 +160,7 @@ Example: reg = <0>; replicator_out_port0: endpoint { remote-endpoint = <&etb_in_port>;
coresight,hwid = <0>; }; };
@@ -161,15 +168,17 @@ Example: reg = <1>; replicator_out_port1: endpoint { remote-endpoint = <&tpiu_in_port>;
coresight,hwid = <1>; }; };
/* replicator input port */ port@2 {
reg = <0>;
reg = <1>;
This will still get flagged as an error. reg must be 2 here.
Rob
Hi Rob,
On 12/06/18 21:48, Rob Herring wrote:
On Fri, Jun 01, 2018 at 02:16:05PM +0100, Suzuki K Poulose wrote:
The coresight drivers relied on default bindings for graph in DT, while reusing the "reg" field of the "ports" to indicate the actual hardware port number for the connections. However, with the rules getting stricter w.r.t to the address mismatch with the label, it is no longer possible to use the port address field for the hardware port number. Hence, we add an explicit property to denote the hardware port number, "coresight,hwid" which must be specified for each "endpoint".
Cc: Mathieu Poirier mathieu.poirier@linaro.org Cc: Sudeep Holla sudeep.holla@arm.com Cc: Rob Herring robh@kernel.org Signed-off-by: Suzuki K Poulose suzuki.poulose@arm.com
.../devicetree/bindings/arm/coresight.txt | 26 +++++++++--- drivers/hwtracing/coresight/of_coresight.c | 46 ++++++++++++++++------ 2 files changed, 54 insertions(+), 18 deletions(-)
diff --git a/Documentation/devicetree/bindings/arm/coresight.txt b/Documentation/devicetree/bindings/arm/coresight.txt index bd36e40..385581a 100644 --- a/Documentation/devicetree/bindings/arm/coresight.txt +++ b/Documentation/devicetree/bindings/arm/coresight.txt @@ -104,7 +104,11 @@ properties to uniquely identify the connection details. "slave-mode"
- Hardware Port number at the component:
- The hardware port number is assumed to be the address of the "port" component.
- (Obsolete) The hardware port number is assumed to be the address of the "port" component.
- Each "endpoint" must define the hardware port of the local end of the
connection using the following property:
- "coresight,hwid" - 32bit integer, hardware port number at the local end.
"coresight" is not a vendor and properties are in the form [<vendor>,]<prop-name>.
OK. The issue here is that a coresight component could be an Arm IP or a custom partner IP. So, the vendor could be either arm or the partner id. However, this property is kind of a generic one for the Coresight family, which is why we opted for "coresight". What is the guideline for such cases ?
Or in other words I see the following possible options :
1) coresight,hwid - coresight generic 2) arm,coresight-hwid - arm vendor, however the device could be from any vendor. 3) hwid - Generic 4) none of the above, something completely different.
What do you recommend from the above ?
Example: @@ -120,6 +124,7 @@ Example: etb_in_port: endpoint@0 {
There shouldn't be a unit address here because there is no reg property.
slave-mode; remote-endpoint = <&replicator_out_port0>;
coresight,hwid = <0>;
It doesn't make sense for these to be in the endpoint. If you had multiple endpoints, then you would have to duplicate it. "ports" are a single data stream. "endpoints" are connections to that stream. So if you have a muxed (input) or fanout/1-to-many (output) connection, then you have multiple endpoints.
We do have many-to-1 input (e.g, funnels) and 1-to-many outputs (e.g replicators). However, we have (so far) used only one endpoint per port.
Also we could potentially have multiple data streams flowing through the ports, which gets filtered to different ports in 1-to-many components (read programmable-replicator).
So the point is we have a shared path which carries different data streams with mux/demux components. I am open for suggestions based on the above facts.
The same applied to the slave-mode property, but that ship has sailed. No reason to continue that though.
}; };
}; @@ -134,6 +139,7 @@ Example: tpiu_in_port: endpoint@0 { slave-mode; remote-endpoint = <&replicator_out_port1>;
}; };coresight,hwid = <0>; };
@@ -154,6 +160,7 @@ Example: reg = <0>; replicator_out_port0: endpoint { remote-endpoint = <&etb_in_port>;
coresight,hwid = <0>; }; };
@@ -161,15 +168,17 @@ Example: reg = <1>; replicator_out_port1: endpoint { remote-endpoint = <&tpiu_in_port>;
coresight,hwid = <1>; }; };
/* replicator input port */ port@2 {
reg = <0>;
reg = <1>;
This will still get flagged as an error. reg must be 2 here.
Sorry, thats a mistake. I will fix it.
Cheers Suzuki
Suzuki,
Why not use “unit”?
I believe we had this discussion years ago about numbering serial ports and sdhci (i.e. how do you know it’s UART0 or UART1 from just the address? Some SoC’s don’t address sequentially *or* in a forward direction) - I believe it’s not exactly codified in ePAPR, not am I sure where it may be otherwise, but it exists.
I agree with Rob on the slave-mode nonsense, this is an SPI controller concept weirdly stuffed into a directed graph which implicitly tells you the data direction - it’s a rooted tree (just like DT!).
For the case of a funnel each device supplying trace should end up into an input node - numbered with a unit - and all those nodes should point to the output node as endpoints. Describing the hardware as a black box is probably less of a good idea than showing that it’s a funnel, or replicator by showing the internal paths. You wouldn’t need to “number” ports with a unit except where the HW needs to differentiate between them, and you don’t need reg or a node address to do it.
If you really need to parse full graphs in both directions (find root, find leaf) then could we simply introduce properties which list the phandles of all uplink sources, as linked lists point to the list head?
This gives a way to validate that the graph starts and ends the way we expect, and also allows every port to be associated with being a required path between any two devices without parsing the *whole* graph (although you still need to do that to find the route to sinks).
Ta, Matt
Sent from my iPhone
On Jun 13, 2018, at 04:45, Suzuki K Poulose Suzuki.Poulose@arm.com wrote:
Hi Rob,
On 12/06/18 21:48, Rob Herring wrote:
On Fri, Jun 01, 2018 at 02:16:05PM +0100, Suzuki K Poulose wrote: The coresight drivers relied on default bindings for graph in DT, while reusing the "reg" field of the "ports" to indicate the actual hardware port number for the connections. However, with the rules getting stricter w.r.t to the address mismatch with the label, it is no longer possible to use the port address field for the hardware port number. Hence, we add an explicit property to denote the hardware port number, "coresight,hwid" which must be specified for each "endpoint".
Cc: Mathieu Poirier mathieu.poirier@linaro.org Cc: Sudeep Holla sudeep.holla@arm.com Cc: Rob Herring robh@kernel.org Signed-off-by: Suzuki K Poulose suzuki.poulose@arm.com
.../devicetree/bindings/arm/coresight.txt | 26 +++++++++--- drivers/hwtracing/coresight/of_coresight.c | 46 ++++++++++++++++------ 2 files changed, 54 insertions(+), 18 deletions(-)
diff --git a/Documentation/devicetree/bindings/arm/coresight.txt b/Documentation/devicetree/bindings/arm/coresight.txt index bd36e40..385581a 100644 --- a/Documentation/devicetree/bindings/arm/coresight.txt +++ b/Documentation/devicetree/bindings/arm/coresight.txt @@ -104,7 +104,11 @@ properties to uniquely identify the connection details. "slave-mode" * Hardware Port number at the component:
- The hardware port number is assumed to be the address of the "port" component.
- (Obsolete) The hardware port number is assumed to be the address of the "port" component.
- Each "endpoint" must define the hardware port of the local end of the
connection using the following property:
- "coresight,hwid" - 32bit integer, hardware port number at the local end.
"coresight" is not a vendor and properties are in the form [<vendor>,]<prop-name>.
OK. The issue here is that a coresight component could be an Arm IP or a custom partner IP. So, the vendor could be either arm or the partner id. However, this property is kind of a generic one for the Coresight family, which is why we opted for "coresight". What is the guideline for such cases ?
Or in other words I see the following possible options :
- coresight,hwid - coresight generic
- arm,coresight-hwid - arm vendor, however the device could be from any vendor.
- hwid - Generic
- none of the above, something completely different.
What do you recommend from the above ?
- Example:
@@ -120,6 +124,7 @@ Example: etb_in_port: endpoint@0 {
There shouldn't be a unit address here because there is no reg property.
slave-mode; remote-endpoint = <&replicator_out_port0>;
coresight,hwid = <0>;
It doesn't make sense for these to be in the endpoint. If you had multiple endpoints, then you would have to duplicate it. "ports" are a single data stream. "endpoints" are connections to that stream. So if you have a muxed (input) or fanout/1-to-many (output) connection, then you have multiple endpoints.
We do have many-to-1 input (e.g, funnels) and 1-to-many outputs (e.g replicators). However, we have (so far) used only one endpoint per port.
Also we could potentially have multiple data streams flowing through the ports, which gets filtered to different ports in 1-to-many components (read programmable-replicator).
So the point is we have a shared path which carries different data streams with mux/demux components. I am open for suggestions based on the above facts.
The same applied to the slave-mode property, but that ship has sailed. No reason to continue that though.
}; }; };
@@ -134,6 +139,7 @@ Example: tpiu_in_port: endpoint@0 { slave-mode; remote-endpoint = <&replicator_out_port1>;
};coresight,hwid = <0>; }; };
@@ -154,6 +160,7 @@ Example: reg = <0>; replicator_out_port0: endpoint { remote-endpoint = <&etb_in_port>;
coresight,hwid = <0>; }; };
@@ -161,15 +168,17 @@ Example: reg = <1>; replicator_out_port1: endpoint { remote-endpoint = <&tpiu_in_port>;
coresight,hwid = <1>; }; }; /* replicator input port */ port@2 {
reg = <0>;
reg = <1>;
This will still get flagged as an error. reg must be 2 here.
Sorry, thats a mistake. I will fix it.
Cheers Suzuki
IMPORTANT NOTICE: The contents of this email and any attachments are confidential and may also be privileged. If you are not the intended recipient, please notify the sender immediately and do not disclose the contents to any other person, use it for any purpose, or store or copy the information in any medium. Thank you.
Hi Matt,
Thanks for your comments, responses inline.
On 13/06/18 13:49, Matt Sealey wrote:
Suzuki,
Why not use “unit”?
I believe we had this discussion years ago about numbering serial ports and sdhci (i.e. how do you know it’s UART0 or UART1 from just the address? Some SoC’s don’t address sequentially *or* in a forward direction) - I believe it’s not exactly codified in ePAPR, not am I sure where it may be otherwise, but it exists.
We have different situation here. We need to know *the port number* as understood by the hardware, so that we can enable *the specific* port for a given path.
I agree with Rob on the slave-mode nonsense, this is an SPI controller concept weirdly stuffed into a directed graph which implicitly tells you the data direction - it’s a rooted tree (just like DT!).
Btw, the "slave-mode" is not a standard DT graph binding. It is not part of the generic DT graph binding. In fact the generic bindings stay away from the direction aspect and explicitly mentions the same.
For the case of a funnel each device supplying trace should end up into an input node - numbered with a unit - and all those nodes should point to the output node as endpoints. Describing the hardware as a black box is probably less of a good idea than showing that it’s a funnel, or replicator by showing the internal paths. You wouldn’t need to “number” ports with a unit except where the HW needs to differentiate between them, and you don’t need reg or a node address to do it.
As I mentioned above, we need the hardware numbers to enable the "specific" port.
E.g, :
static void funnel_enable_hw(struct funnel_drvdata *drvdata, int port) { u32 functl;
CS_UNLOCK(drvdata->base);
functl = readl_relaxed(drvdata->base + FUNNEL_FUNCTL); functl &= ~FUNNEL_HOLDTIME_MASK; functl |= FUNNEL_HOLDTIME; functl |= (1 << port); writel_relaxed(functl, drvdata->base + FUNNEL_FUNCTL); writel_relaxed(drvdata->priority, drvdata->base + FUNNEL_PRICTL);
CS_LOCK(drvdata->base); }
If you really need to parse full graphs in both directions (find root, find leaf) then could we simply introduce properties which list the phandles of all uplink sources, as linked lists point to the list head?
No we don't need to parse it in both ways, up and down. Btw, the trace paths are not statically created. They are done at runtime, as configured by the user. So all we need to do is have a list of the ports and the devices it is connected to (of course with direction information). I would stay away from duplicating the platform code when something already does a good job.
This gives a way to validate that the graph starts and ends the way we expect, and also allows every port to be associated with being a required path between any two devices without parsing the *whole* graph (although you still need to do that to find the route to sinks).
Coming back to your suggestion of "unit", what does it imply ? Its too generic a term for something as concrete as a port number.
Cheers Suzuki
Ta, Matt
Sent from my iPhone
On Jun 13, 2018, at 04:45, Suzuki K Poulose Suzuki.Poulose@arm.com wrote:
Hi Rob,
On 12/06/18 21:48, Rob Herring wrote:
On Fri, Jun 01, 2018 at 02:16:05PM +0100, Suzuki K Poulose wrote: The coresight drivers relied on default bindings for graph in DT, while reusing the "reg" field of the "ports" to indicate the actual hardware port number for the connections. However, with the rules getting stricter w.r.t to the address mismatch with the label, it is no longer possible to use the port address field for the hardware port number. Hence, we add an explicit property to denote the hardware port number, "coresight,hwid" which must be specified for each "endpoint".
Cc: Mathieu Poirier mathieu.poirier@linaro.org Cc: Sudeep Holla sudeep.holla@arm.com Cc: Rob Herring robh@kernel.org Signed-off-by: Suzuki K Poulose suzuki.poulose@arm.com
.../devicetree/bindings/arm/coresight.txt | 26 +++++++++--- drivers/hwtracing/coresight/of_coresight.c | 46 ++++++++++++++++------ 2 files changed, 54 insertions(+), 18 deletions(-)
diff --git a/Documentation/devicetree/bindings/arm/coresight.txt b/Documentation/devicetree/bindings/arm/coresight.txt index bd36e40..385581a 100644 --- a/Documentation/devicetree/bindings/arm/coresight.txt +++ b/Documentation/devicetree/bindings/arm/coresight.txt @@ -104,7 +104,11 @@ properties to uniquely identify the connection details. "slave-mode" * Hardware Port number at the component:
- The hardware port number is assumed to be the address of the "port" component.
- (Obsolete) The hardware port number is assumed to be the address of the "port" component.
- Each "endpoint" must define the hardware port of the local end of the
connection using the following property:
- "coresight,hwid" - 32bit integer, hardware port number at the local end.
"coresight" is not a vendor and properties are in the form [<vendor>,]<prop-name>.
OK. The issue here is that a coresight component could be an Arm IP or a custom partner IP. So, the vendor could be either arm or the partner id. However, this property is kind of a generic one for the Coresight family, which is why we opted for "coresight". What is the guideline for such cases ?
Or in other words I see the following possible options :
- coresight,hwid - coresight generic
- arm,coresight-hwid - arm vendor, however the device could be from any vendor.
- hwid - Generic
- none of the above, something completely different.
What do you recommend from the above ?
Example:
@@ -120,6 +124,7 @@ Example: etb_in_port: endpoint@0 {
There shouldn't be a unit address here because there is no reg property.
slave-mode; remote-endpoint = <&replicator_out_port0>;
coresight,hwid = <0>;
It doesn't make sense for these to be in the endpoint. If you had multiple endpoints, then you would have to duplicate it. "ports" are a single data stream. "endpoints" are connections to that stream. So if you have a muxed (input) or fanout/1-to-many (output) connection, then you have multiple endpoints.
We do have many-to-1 input (e.g, funnels) and 1-to-many outputs (e.g replicators). However, we have (so far) used only one endpoint per port.
Also we could potentially have multiple data streams flowing through the ports, which gets filtered to different ports in 1-to-many components (read programmable-replicator).
So the point is we have a shared path which carries different data streams with mux/demux components. I am open for suggestions based on the above facts.
The same applied to the slave-mode property, but that ship has sailed. No reason to continue that though.
}; }; };
@@ -134,6 +139,7 @@ Example: tpiu_in_port: endpoint@0 { slave-mode; remote-endpoint = <&replicator_out_port1>;
coresight,hwid = <0>; }; }; };
@@ -154,6 +160,7 @@ Example: reg = <0>; replicator_out_port0: endpoint { remote-endpoint = <&etb_in_port>;
@@ -161,15 +168,17 @@ Example: reg = <1>; replicator_out_port1: endpoint { remote-endpoint = <&tpiu_in_port>;coresight,hwid = <0>; }; };
coresight,hwid = <1>; }; }; /* replicator input port */ port@2 {
reg = <0>;
reg = <1>;
This will still get flagged as an error. reg must be 2 here.
Sorry, thats a mistake. I will fix it.
Cheers Suzuki
On Wed, Jun 13, 2018 at 7:35 AM, Suzuki K Poulose Suzuki.Poulose@arm.com wrote:
Hi Matt,
Thanks for your comments, responses inline.
On 13/06/18 13:49, Matt Sealey wrote:
Suzuki,
Why not use “unit”?
I believe we had this discussion years ago about numbering serial ports and sdhci (i.e. how do you know it’s UART0 or UART1 from just the address? Some SoC’s don’t address sequentially *or* in a forward direction) - I believe it’s not exactly codified in ePAPR, not am I sure where it may be otherwise, but it exists.
We have different situation here. We need to know *the port number* as understood by the hardware, so that we can enable *the specific* port for a given path.
I agree with Rob on the slave-mode nonsense, this is an SPI controller concept weirdly stuffed into a directed graph which implicitly tells you the data direction - it’s a rooted tree (just like DT!).
OF graph is not directional. All links must be bi-directional and in fact dtc checks that now. The parent node should know the numbering and direction of each port.
Btw, the "slave-mode" is not a standard DT graph binding. It is not part of the generic DT graph binding. In fact the generic bindings stay away from the direction aspect and explicitly mentions the same.
I really don't like slave-mode nor coresight,hwid.
I would prefer to see getting rid of both and splitting ports into "in-ports" and "out-ports" nodes instead of a single "ports" node. Then you don't need any of these properties and reg can be used as the hwid.
Rob
Hi Suzuki,
Why not use “unit”?
I believe we had this discussion years ago about numbering serial ports and sdhci (i.e. how do you know it’s UART0 or UART1 from just the address? Some SoC’s don’t address sequentially *or* in a forward direction) - I believe it’s not exactly codified in ePAPR, not am I sure where it may be otherwise, but it exists.
We have different situation here. We need to know *the port number* as understood by the hardware, so that we can enable *the specific* port for a given path.
For the purposes of abstraction, each port will have the property of having a node which is pointed to by other nodes, and in the case of a true ATB endpoint, no other nodes behind it.
It doesn't matter what the HW numbers it as as long as the driver can derive it from whatever you put in the DT. So a funnel (which is ~8 ports muxed into one output):
f1p0: port { unit = <0>; endpoint = <&f1out>; }; f1p1: port { unit = <4>; endpoint = <&f1out>; }; f1out: port { endpoint = <&etf1>; };
"unit" here is specific to the driver's understanding of ports within it's own cycle of the graph. For a replicator you can invert the logic - input ports don't need a unit, but the two outputs are filtered in CoreSight not by leg but by transiting ATB ID in groups of 16 IDs. In that case maybe you would want to describe all 8 possible units on each leg with the first ID it would filter? Or just list tuples of filter IDs <id, first, last>
Who cares, really, as long as the driver knows what it means.
You don't need to namespace every property.
As I mentioned above, we need the hardware numbers to enable the "specific" port.
Okay and how is this not able to be prescribed in a binding for "arm,coresight-funnel" that:
"input ports are numbered from 0 to N where N is the maximum input port number. This number is identified with the "unit" property, which directly corresponds to the bit position in the funnel Ctrl_Reg register, and the bit position multiplied by 3 for each 3-bit priority in the funnel Priority_Ctrl_Reg, with N having a maximum of the defined register bitfield DEVID[PORTCOUNT], minus one, for that component"
Or a replicator:
"output ports are numbered per the CoreSight ATB Replicator specification, unit corresponding to the IDFILTERn register controlling ID filters for that leg, with a maximum of the defined register bitfield DEVID[PORTNUM], minus one"
One could clarify it, even, with labels for readability ("label" definitely is a well defined if also completely arbitrary property).
..
static void funnel_enable_hw(struct funnel_drvdata *drvdata, int port) { u32 functl;
CS_UNLOCK(drvdata->base); functl = readl_relaxed(drvdata->base + FUNNEL_FUNCTL); functl &= ~FUNNEL_HOLDTIME_MASK; functl |= FUNNEL_HOLDTIME; functl |= (1 << port); writel_relaxed(functl, drvdata->base + FUNNEL_FUNCTL); writel_relaxed(drvdata->priority, drvdata->base + FUNNEL_PRICTL); CS_LOCK(drvdata->base);
}
No we don't need to parse it in both ways, up and down. Btw, the trace paths are not statically created. They are done at runtime, as configured by the user.
You do realize this isn't how the hardware works, correct?
Trace paths are fixed, they may diverge with different configurations, but the full CoreSight topology (all funnels, replicators and intermediary Components) is entirely unchangeable.
The DT should provide the information to provide a reference acyclic directed graph of the entire topology (or entirely reasonably programmable topology where at all possible) - if a user wants to trace from ETM_0 then they only have particular paths to particular sinks, for instance ETM_0 and ETF_0 may be on their own path, so you cannot just "configure as a user" a path from ETM_1 to ETF_0 since there isn't one.
Walking said graphs with the knowledge that CoreSight specifically disallows loopbacks in ATB topology is basic computer science problem - literally a matter of topological sorting. But let's build a graph once and traverse it - don't build the graph partially each time or try and build it to cross-check every time. The paths are wires in the design, lets not fake to the user that there is any configurability in that or try and encode that in the DT.
Coming back to your suggestion of "unit", what does it imply ?
Whatever the driver likes. For uart and mmc, it was just a spurious number but it could be applied as the end of, say, ttyS<N> or mmcblk<N>p3 or used in any other driver-specific manner. The number you put in is up to you, but the valid numbers would be in the binding for that particular device.
Its too generic a term for something as concrete as a port number.
Is it?
Why would you need a whole other property type to encode a u32 that describes an arbitrary number specific to that hardware device?
Ta, Matt
IMPORTANT NOTICE: The contents of this email and any attachments are confidential and may also be privileged. If you are not the intended recipient, please notify the sender immediately and do not disclose the contents to any other person, use it for any purpose, or store or copy the information in any medium. Thank you.
Hi Matt,
On 13/06/18 16:47, Matt Sealey wrote:
Hi Suzuki,
Why not use “unit”?
I believe we had this discussion years ago about numbering serial ports and sdhci (i.e. how do you know it’s UART0 or UART1 from just the address? Some SoC’s don’t address sequentially *or* in a forward direction) - I believe it’s not exactly codified in ePAPR, not am I sure where it may be otherwise, but it exists.
We have different situation here. We need to know *the port number* as understood by the hardware, so that we can enable *the specific* port for a given path.
For the purposes of abstraction, each port will have the property of having a node which is pointed to by other nodes, and in the case of a true ATB endpoint, no other nodes behind it.
It doesn't matter what the HW numbers it as as long as the driver can derive it from whatever you put in the DT. So a funnel (which is ~8 ports muxed into one output):
f1p0: port { unit = <0>; endpoint = <&f1out>; }; f1p1: port { unit = <4>; endpoint = <&f1out>; }; f1out: port { endpoint = <&etf1>; };
"unit" here is specific to the driver's understanding of ports within it's
I may be missing, but is "unit" something that already exists and used by DT bindings already ? Or is this something new that we are proposing ?
own cycle of the graph. For a replicator you can invert the logic - input ports don't need a unit, but the two outputs are filtered in CoreSight not
I would prefer to make the new property mandatory for all the ports to avoid a potential problem in the future.
How do you represent a TMC-ETF which has one input and one output connection ? Also what happens if we ever get a component which has m-to-n connections ?
by leg but by transiting ATB ID in groups of 16 IDs. In that case maybe you would want to describe all 8 possible units on each leg with the first ID it would filter? Or just list tuples of filter IDs <id, first, last>
I am failing to follow the ATB ID group description above. As per the TRM, e.g, replicator filters the "trace stream" based on the "trace ID", which I believe can be programmed via IDFILTER<n> register. So why would we need that to be part of the DT ?
Who cares, really, as long as the driver knows what it means.
You don't need to namespace every property.
As I mentioned above, we need the hardware numbers to enable the "specific" port.
Okay and how is this not able to be prescribed in a binding for "arm,coresight-funnel" that:
"input ports are numbered from 0 to N where N is the maximum input port number. This number is identified with the "unit" property, which directly corresponds to the bit position in the funnel Ctrl_Reg register, and the bit position multiplied by 3 for each 3-bit priority in the funnel Priority_Ctrl_Reg, with N having a maximum of the defined register bitfield DEVID[PORTCOUNT], minus one, for that component"
The description looks over complicated to me at least, even after having known bit of the programming interface of the components. I would prefer staying closer to the terms used in the TRM ("slave/master" interfaces) and make it easier for people to write the DT.
Or a replicator:
"output ports are numbered per the CoreSight ATB Replicator specification, unit corresponding to the IDFILTERn register controlling ID filters for that leg, with a maximum of the defined register bitfield DEVID[PORTNUM], minus one"
One could clarify it, even, with labels for readability ("label" definitely is a well defined if also completely arbitrary property).
..
static void funnel_enable_hw(struct funnel_drvdata *drvdata, int port) { u32 functl;
CS_UNLOCK(drvdata->base); functl = readl_relaxed(drvdata->base + FUNNEL_FUNCTL); functl &= ~FUNNEL_HOLDTIME_MASK; functl |= FUNNEL_HOLDTIME; functl |= (1 << port); writel_relaxed(functl, drvdata->base + FUNNEL_FUNCTL); writel_relaxed(drvdata->priority, drvdata->base + FUNNEL_PRICTL); CS_LOCK(drvdata->base);
}
No we don't need to parse it in both ways, up and down. Btw, the trace paths are not statically created. They are done at runtime, as configured by the user.
You do realize this isn't how the hardware works, correct?
The "trace paths" mentioned above were indeed the software path, which was constructed at runtime. The graph connections are indeed a one time parsing at probe time and as you said they don't change. And by configuring, I mean selecting the "source" and the "sink".
Trace paths are fixed, they may diverge with different configurations, but the full CoreSight topology (all funnels, replicators and intermediary Components) is entirely unchangeable.
The DT should provide the information to provide a reference acyclic directed graph of the entire topology (or entirely reasonably programmable topology where at all possible) - if a user wants to trace from ETM_0 then they only have particular paths to particular sinks, for instance ETM_0 and ETF_0 may be on their own path, so you cannot just "configure as a user" a path from ETM_1 to ETF_0 since there isn't one.
Walking said graphs with the knowledge that CoreSight specifically disallows loopbacks in ATB topology is basic computer science problem - literally a matter of topological sorting. But let's build a graph once and traverse it - don't build the graph partially each time or try and build it to cross-check every time. The paths are wires in the design, lets not fake to the user that there is any configurability in that or try and encode that in the DT.
Sorry for the confusion, as explained above, it is indeed a one time pass.
Coming back to your suggestion of "unit", what does it imply ?
Whatever the driver likes. For uart and mmc, it was just a spurious number but it could be applied as the end of, say, ttyS<N> or mmcblk<N>p3 or used in any other driver-specific manner. The number you put in is up to you, but the valid numbers would be in the binding for that particular device.
Its too generic a term for something as concrete as a port number.
Is it?
Why would you need a whole other property type to encode a u32 that describes an arbitrary number specific to that hardware device?
So, if the suggestion is to use an existing property "unit", I am fine with it, if people agree to it.
Thanks for the comments.
Cheers, Suzuki
On 13 June 2018 at 11:07, Suzuki K Poulose Suzuki.Poulose@arm.com wrote:
Hi Matt,
On 13/06/18 16:47, Matt Sealey wrote:
Hi Suzuki,
Why not use “unit”?
I believe we had this discussion years ago about numbering serial ports and sdhci (i.e. how do you know it’s UART0 or UART1 from just the address? Some SoC’s don’t address sequentially *or* in a forward direction) - I believe it’s not exactly codified in ePAPR, not am I sure where it may be otherwise, but it exists.
We have different situation here. We need to know *the port number* as understood by the hardware, so that we can enable *the specific* port for a given path.
For the purposes of abstraction, each port will have the property of having a node which is pointed to by other nodes, and in the case of a true ATB endpoint, no other nodes behind it.
It doesn't matter what the HW numbers it as as long as the driver can derive it from whatever you put in the DT. So a funnel (which is ~8 ports muxed into one output):
f1p0: port { unit = <0>; endpoint = <&f1out>; }; f1p1: port { unit = <4>; endpoint = <&f1out>; }; f1out: port { endpoint = <&etf1>; };
"unit" here is specific to the driver's understanding of ports within it's
I may be missing, but is "unit" something that already exists and used by DT bindings already ? Or is this something new that we are proposing ?
own cycle of the graph. For a replicator you can invert the logic - input ports don't need a unit, but the two outputs are filtered in CoreSight not
I would prefer to make the new property mandatory for all the ports to avoid a potential problem in the future.
How do you represent a TMC-ETF which has one input and one output connection ? Also what happens if we ever get a component which has m-to-n connections ?
by leg but by transiting ATB ID in groups of 16 IDs. In that case maybe you would want to describe all 8 possible units on each leg with the first ID it would filter? Or just list tuples of filter IDs <id, first, last>
I am failing to follow the ATB ID group description above. As per the TRM, e.g, replicator filters the "trace stream" based on the "trace ID", which I believe can be programmed via IDFILTER<n> register. So why would we need that to be part of the DT ?
Who cares, really, as long as the driver knows what it means.
You don't need to namespace every property.
As I mentioned above, we need the hardware numbers to enable the "specific" port.
Okay and how is this not able to be prescribed in a binding for "arm,coresight-funnel" that:
"input ports are numbered from 0 to N where N is the maximum input port number. This number is identified with the "unit" property, which directly corresponds to the bit position in the funnel Ctrl_Reg register, and the bit position multiplied by 3 for each 3-bit priority in the funnel Priority_Ctrl_Reg, with N having a maximum of the defined register bitfield DEVID[PORTCOUNT], minus one, for that component"
The description looks over complicated to me at least, even after having known bit of the programming interface of the components. I would prefer staying closer to the terms used in the TRM ("slave/master" interfaces) and make it easier for people to write the DT.
Or a replicator:
"output ports are numbered per the CoreSight ATB Replicator specification, unit corresponding to the IDFILTERn register controlling ID filters for that leg, with a maximum of the defined register bitfield DEVID[PORTNUM], minus one"
One could clarify it, even, with labels for readability ("label" definitely is a well defined if also completely arbitrary property).
..
static void funnel_enable_hw(struct funnel_drvdata *drvdata, int port) { u32 functl;
CS_UNLOCK(drvdata->base); functl = readl_relaxed(drvdata->base + FUNNEL_FUNCTL); functl &= ~FUNNEL_HOLDTIME_MASK; functl |= FUNNEL_HOLDTIME; functl |= (1 << port); writel_relaxed(functl, drvdata->base + FUNNEL_FUNCTL); writel_relaxed(drvdata->priority, drvdata->base +
FUNNEL_PRICTL);
CS_LOCK(drvdata->base);
}
No we don't need to parse it in both ways, up and down. Btw, the trace paths are not statically created. They are done at runtime, as configured by the user.
You do realize this isn't how the hardware works, correct?
The "trace paths" mentioned above were indeed the software path, which was constructed at runtime. The graph connections are indeed a one time parsing at probe time and as you said they don't change. And by configuring, I mean selecting the "source" and the "sink".
Trace paths are fixed, they may diverge with different configurations, but the full CoreSight topology (all funnels, replicators and intermediary Components) is entirely unchangeable.
The DT should provide the information to provide a reference acyclic directed graph of the entire topology (or entirely reasonably programmable topology where at all possible) - if a user wants to trace from ETM_0 then they only have particular paths to particular sinks, for instance ETM_0 and ETF_0 may be on their own path, so you cannot just "configure as a user" a path from ETM_1 to ETF_0 since there isn't one.
Walking said graphs with the knowledge that CoreSight specifically disallows loopbacks in ATB topology is basic computer science problem - literally a matter of topological sorting. But let's build a graph once and traverse it - don't build the graph partially each time or try and build it to cross-check every time. The paths are wires in the design, lets not fake to the user that there is any configurability in that or try and encode that in the DT.
Sorry for the confusion, as explained above, it is indeed a one time pass.
Coming back to your suggestion of "unit", what does it imply ?
Whatever the driver likes. For uart and mmc, it was just a spurious number but it could be applied as the end of, say, ttyS<N> or mmcblk<N>p3 or used in any other driver-specific manner. The number you put in is up to you, but the valid numbers would be in the binding for that particular device.
Its too generic a term for something as concrete as a port number.
Is it?
Why would you need a whole other property type to encode a u32 that describes an arbitrary number specific to that hardware device?
So, if the suggestion is to use an existing property "unit", I am fine with it, if people agree to it.
If we're going to have something sharply different than ACPI I prefer Rob's idea.
Mathieu
Thanks for the comments.
Cheers, Suzuki
-----Original Message----- From: Mathieu Poirier mathieu.poirier@linaro.org
So, if the suggestion is to use an existing property "unit", I am fine with it, if people agree to it.
If we're going to have something sharply different than ACPI I prefer Rob's idea.
What are you trying to say about being sharply different than ACPI?
Ta, Matt
IMPORTANT NOTICE: The contents of this email and any attachments are confidential and may also be privileged. If you are not the intended recipient, please notify the sender immediately and do not disclose the contents to any other person, use it for any purpose, or store or copy the information in any medium. Thank you.
On 13/06/18 22:07, Matt Sealey wrote:
-----Original Message----- From: Mathieu Poirier mathieu.poirier@linaro.org
So, if the suggestion is to use an existing property "unit", I am fine with it, if people agree to it.
If we're going to have something sharply different than ACPI I prefer Rob's idea.
No, the above comment is about using "unit" ( if it is a standard property for specifying something specific to hardware) instead of "coresight,hwid". I would prefer to stick to the DT graph bindings, because :
1) The connections are bi-directional => Well, not necessarily bi-directional in terms of the data flow. But the connection information is critical. i.e, we need information about both the end-points of a connection, which the DT graph bindings solves.
All we are missing is a way for specifying the "hardware port" number and the direction of flow. I don't see why do we need to create something new just for these two properties for something that exists today and works reasonably well for the usecase.
What are you trying to say about being sharply different than ACPI?
The proposed Coresight ACPI draft bindings are based on the ACPI Graph bindings (just like the DT graph bindings and is compatible with it, in terms of the APIs. i.e, fwnode_graph_* operations work for both ACPI and DT alike).
So, what Mathieu, in turn means is, if we depart from the DT Graph bindings, which I personally don't see any benefit in.
Suzuki
On Thu, Jun 14, 2018 at 2:53 AM, Suzuki K Poulose Suzuki.Poulose@arm.com wrote:
On 13/06/18 22:07, Matt Sealey wrote:
-----Original Message----- From: Mathieu Poirier mathieu.poirier@linaro.org
So, if the suggestion is to use an existing property "unit", I am fine with it, if people agree to it.
If we're going to have something sharply different than ACPI I prefer Rob's idea.
No, the above comment is about using "unit" ( if it is a standard property for specifying something specific to hardware) instead of "coresight,hwid". I would prefer to stick to the DT graph bindings, because :
"unit" is not a standard property and I don't like it either.
- The connections are bi-directional => Well, not necessarily
bi-directional in terms of the data flow. But the connection information is critical. i.e, we need information about both the end-points of a connection, which the DT graph bindings solves.
All we are missing is a way for specifying the "hardware port" number and the direction of flow. I don't see why do we need to create something new just for these two properties for something that exists today and works reasonably well for the usecase.
If you have "in-ports" and "out-ports" nodes, then that gives you direction and you can use reg for the "hardware port".
in-ports { port@0 { reg = <0>; endpoint {...}; }; port@1 { reg = <1>; endpoint {...}; }; }; out-ports { port@0 { reg = <0>; endpoint {...}; }; };
I'll need to check, but dtc may need an update to not warn about this.
What are you trying to say about being sharply different than ACPI?
The proposed Coresight ACPI draft bindings are based on the ACPI Graph bindings (just like the DT graph bindings and is compatible with it, in terms of the APIs. i.e, fwnode_graph_* operations work for both ACPI and DT alike).
So, what Mathieu, in turn means is, if we depart from the DT Graph bindings, which I personally don't see any benefit in.
If DT bindings can be reused for ACPI, that's fine, but don't expect any DT bindings to be accepted simply because they match ACPI bindings.
Rob
Hi Rob,
To take this in a somewhat different direction...
No, the above comment is about using "unit" ( if it is a standard property for specifying something specific to hardware) instead of "coresight,hwid". I would prefer to stick to the DT graph bindings, because :
"unit" is not a standard property and I don't like it either.
Fair enough.
If you have "in-ports" and "out-ports" nodes, then that gives you direction and you can use reg for the "hardware port".
in-ports { port@0 { reg = <0>; endpoint {...}; }; port@1 { reg = <1>; endpoint {...}; }; }; out-ports { port@0 { reg = <0>; endpoint {...}; }; };
I'll need to check, but dtc may need an update to not warn about this.
If the requirement that unit-address and the low #address-cells of reg now being forced by a validation tool is screwing us over here, we can't really change the tool; that's a IEEE 1275-1994 requirement we'd be hacking around.
Here's a thought - why don't we define the ports in each component in a separate graph? Describing the ATB topology as a bus with a graph structure and then having the components simply reference the port nodes would make it much easier to design.
Part of the problem is trying to describe an ATB bus via a component on an APB bus. You lose all the niceties of describing a bus with bus subcomponents. Lets take the ATB bus outside.. by describing the ingress and egress of the component you have no idea where in the graph you are at the point of entry (you could start parsing at a funnel, which means travelling around looking for other units that match other compatibles).
If the CoreSight subsystem could have a graph pre-made of the full topology, then the components can point to how they wrap parts of that topology. You can also do away with ridiculous non-programmable funnels and replicator nodes, since the trace graph would encapsulate that information without having to instantiate a stub driver for it.
That doesn't solve 'unit' or 'unit-address' or 'reg' or anything but it would keep us in graph bindings and abstract the ATB topology from the components. Other fun stuff; describing bridge components and bus widths within the graph could give abilities to describe bandwidths over each trace path.
In any case, what happens when you have to decide what your funnel port priorities are, you'll have to define a new property for that, and it won't be 'reg'.
Trying not to add anything to the graph bindings is one thing but trying to shoehorn it in either by doing that or inventing wholly device-specific properties are just as bad.
Perhaps we can use the path@unit-address:arguments <-- parameters here to add extra information about the port. 'my-args' would pull it out in Forth, I don't know how FDT code deals with it (but there should be something, since we use it for console definition in /chosen). They're entirely specific to the node in question, but not used in path matching.
Why can't we decide on a graph-binding update that allows specifying something simple as a demultiplexer output in a way the driver can understand and map to the hardware?
If DT bindings can be reused for ACPI, that's fine
However in my opinion not the preferred way to do it..
any DT bindings to be accepted simply because they match ACPI bindings.
I'm sure ACPI has capability of a much classier way of describing things, but I have some fear that it's just OF bindings stuffed in a _DSD.. DT and ACPI have the responsibility of shouldering the burden of describing hardware. Any attempts to try and make some commonality to promote brevity of Linux code is totally out of scope..
You can always abstract whatever definition into whatever the Linux drivers need at the time. That's kind of the point. Locking in to 'how it's currently coded' is stifling when realizing the first attempt didn't actually adequately do what it was intended.
Ta, Matt IMPORTANT NOTICE: The contents of this email and any attachments are confidential and may also be privileged. If you are not the intended recipient, please notify the sender immediately and do not disclose the contents to any other person, use it for any purpose, or store or copy the information in any medium. Thank you.
On 14/06/18 14:59, Rob Herring wrote:
On Thu, Jun 14, 2018 at 2:53 AM, Suzuki K Poulose Suzuki.Poulose@arm.com wrote:
On 13/06/18 22:07, Matt Sealey wrote:
-----Original Message----- From: Mathieu Poirier mathieu.poirier@linaro.org
So, if the suggestion is to use an existing property "unit", I am fine with it, if people agree to it.
If we're going to have something sharply different than ACPI I prefer Rob's idea.
No, the above comment is about using "unit" ( if it is a standard property for specifying something specific to hardware) instead of "coresight,hwid". I would prefer to stick to the DT graph bindings, because :
"unit" is not a standard property and I don't like it either.
- The connections are bi-directional => Well, not necessarily
bi-directional in terms of the data flow. But the connection information is critical. i.e, we need information about both the end-points of a connection, which the DT graph bindings solves.
All we are missing is a way for specifying the "hardware port" number and the direction of flow. I don't see why do we need to create something new just for these two properties for something that exists today and works reasonably well for the usecase.
Rob,
If you have "in-ports" and "out-ports" nodes, then that gives you direction and you can use reg for the "hardware port".
in-ports { port@0 { reg = <0>; endpoint {...}; }; port@1 { reg = <1>; endpoint {...}; }; }; out-ports { port@0 { reg = <0>; endpoint {...}; }; };
I'll need to check, but dtc may need an update to not warn about this.
Ok, that looks good.
What are you trying to say about being sharply different than ACPI?
The proposed Coresight ACPI draft bindings are based on the ACPI Graph bindings (just like the DT graph bindings and is compatible with it, in terms of the APIs. i.e, fwnode_graph_* operations work for both ACPI and DT alike).
So, what Mathieu, in turn means is, if we depart from the DT Graph bindings, which I personally don't see any benefit in.
If DT bindings can be reused for ACPI, that's fine, but don't expect any DT bindings to be accepted simply because they match ACPI bindings.
The proposed bindings are not making it compatible with the ACPI. In fact, the ACPI bindings do need something similar to give us an explicit hardware port number, which needs to be worked out. The only common theme shared between the proposed ACPI and current DT bindings are the Generic Graph bindings for describing the connections, which allows sharing the parsing code independent of the platform, using fwnode_ops.
Suzuki
Hi Rob,
On 14/06/18 14:59, Rob Herring wrote:
On Thu, Jun 14, 2018 at 2:53 AM, Suzuki K Poulose Suzuki.Poulose@arm.com wrote:
On 13/06/18 22:07, Matt Sealey wrote:
-----Original Message----- From: Mathieu Poirier mathieu.poirier@linaro.org
So, if the suggestion is to use an existing property "unit", I am fine with it, if people agree to it.
If we're going to have something sharply different than ACPI I prefer Rob's idea.
No, the above comment is about using "unit" ( if it is a standard property for specifying something specific to hardware) instead of "coresight,hwid". I would prefer to stick to the DT graph bindings, because :
"unit" is not a standard property and I don't like it either.
- The connections are bi-directional => Well, not necessarily
bi-directional in terms of the data flow. But the connection information is critical. i.e, we need information about both the end-points of a connection, which the DT graph bindings solves.
All we are missing is a way for specifying the "hardware port" number and the direction of flow. I don't see why do we need to create something new just for these two properties for something that exists today and works reasonably well for the usecase.
If you have "in-ports" and "out-ports" nodes, then that gives you direction and you can use reg for the "hardware port".
in-ports { port@0 { reg = <0>; endpoint {...}; }; port@1 { reg = <1>; endpoint {...}; }; }; out-ports { port@0 { reg = <0>; endpoint {...}; }; };
I'll need to check, but dtc may need an update to not warn about this.
I did a quick check with the upstream dtc tool and the above form is doesn't generate any errors.
Mathieu, Rob,
Shall I proceed with the proposal above ?
Suzuki
On Tue, 3 Jul 2018 at 03:44, Suzuki K Poulose Suzuki.Poulose@arm.com wrote:
Hi Rob,
On 14/06/18 14:59, Rob Herring wrote:
On Thu, Jun 14, 2018 at 2:53 AM, Suzuki K Poulose Suzuki.Poulose@arm.com wrote:
On 13/06/18 22:07, Matt Sealey wrote:
-----Original Message----- From: Mathieu Poirier mathieu.poirier@linaro.org
So, if the suggestion is to use an existing property "unit", I am
fine
with it, if people agree to it.
If we're going to have something sharply different than ACPI I prefer Rob's idea.
No, the above comment is about using "unit" ( if it is a standard
property
for specifying something specific to hardware) instead of
"coresight,hwid".
I would prefer to stick to the DT graph bindings, because :
"unit" is not a standard property and I don't like it either.
- The connections are bi-directional => Well, not necessarily
bi-directional in terms of the data flow. But the connection information is critical.
i.e,
we need information about both the end-points of a connection, which
the DT
graph bindings solves.
All we are missing is a way for specifying the "hardware port" number
and
the direction of flow. I don't see why do we need to create something new
just
for these two properties for something that exists today and works
reasonably
well for the usecase.
If you have "in-ports" and "out-ports" nodes, then that gives you direction and you can use reg for the "hardware port".
in-ports { port@0 { reg = <0>; endpoint {...}; }; port@1 { reg = <1>; endpoint {...}; }; }; out-ports { port@0 { reg = <0>; endpoint {...}; }; };
I'll need to check, but dtc may need an update to not warn about this.
I did a quick check with the upstream dtc tool and the above form is doesn't generate any errors.
Mathieu, Rob,
Shall I proceed with the proposal above ?
Yes - at the very least it will provide a new reference point to work form.
Thanks, Mathieu
Suzuki
So far we have relied on an undocumented property "slave-mode", to indicate if the given port is input or not. Since we are redefining the coresight bindings, define new property for the "direction" of data flow for a given connection endpoint in the device.
Each endpoint must define the following property.
- "direction" : 0 => Port is input 1 => Port is output
Cc: Mathieu Poirier mathieu.poirier@linaro.org Signed-off-by: Suzuki K Poulose suzuki.poulose@arm.com --- drivers/hwtracing/coresight/of_coresight.c | 20 ++++++++++++++++---- 1 file changed, 16 insertions(+), 4 deletions(-)
diff --git a/drivers/hwtracing/coresight/of_coresight.c b/drivers/hwtracing/coresight/of_coresight.c index 99d7a9c..63c1668 100644 --- a/drivers/hwtracing/coresight/of_coresight.c +++ b/drivers/hwtracing/coresight/of_coresight.c @@ -52,7 +52,19 @@ of_coresight_get_endpoint_device(struct device_node *endpoint) endpoint, of_dev_node_match); }
-static void of_coresight_get_ports(const struct device_node *node, +static bool of_coresight_ep_is_input(struct device *dev, struct device_node *ep_node) +{ + u32 dir; + + if (!of_property_read_u32(ep_node, "direction", &dir)) + return dir == 0; + + dev_warn_once(dev, "Missing mandatory "direction" property!\n"); + return of_property_read_bool(ep_node, "slave-mode"); +} + +static void of_coresight_get_ports(struct device *dev, + const struct device_node *node, int *nr_inport, int *nr_outport) { struct device_node *ep = NULL; @@ -63,7 +75,7 @@ static void of_coresight_get_ports(const struct device_node *node, if (!ep) break;
- if (of_property_read_bool(ep, "slave-mode")) + if (of_coresight_ep_is_input(dev, ep)) in++; else out++; @@ -149,7 +161,7 @@ of_get_coresight_platform_data(struct device *dev, pdata->name = dev_name(dev);
/* Get the number of input and output port for this component */ - of_coresight_get_ports(node, &pdata->nr_inport, &pdata->nr_outport); + of_coresight_get_ports(dev, node, &pdata->nr_inport, &pdata->nr_outport);
if (pdata->nr_outport) { ret = of_coresight_alloc_memory(dev, pdata); @@ -168,7 +180,7 @@ of_get_coresight_platform_data(struct device *dev, * No need to deal with input ports, processing for as * processing for output ports will deal with them. */ - if (of_find_property(ep, "slave-mode", NULL)) + if (of_coresight_ep_is_input(dev, ep)) continue;
outport = of_graph_ep_coresight_get_port_id(dev, ep);
On Fri, Jun 01, 2018 at 02:16:06PM +0100, Suzuki K Poulose wrote:
So far we have relied on an undocumented property "slave-mode", to indicate if the given port is input or not. Since we are redefining the coresight bindings, define new property for the "direction" of data flow for a given connection endpoint in the device.
Each endpoint must define the following property.
- "direction" : 0 => Port is input 1 => Port is output
Cc: Mathieu Poirier mathieu.poirier@linaro.org Signed-off-by: Suzuki K Poulose suzuki.poulose@arm.com
drivers/hwtracing/coresight/of_coresight.c | 20 ++++++++++++++++----
You haven't documented the binding in bindings/arm/coresight.txt the same way you did with "coresight,hwid". I'm guessing you simply forgot to do a "git add" on the file when preparing the patchset.
1 file changed, 16 insertions(+), 4 deletions(-)
diff --git a/drivers/hwtracing/coresight/of_coresight.c b/drivers/hwtracing/coresight/of_coresight.c index 99d7a9c..63c1668 100644 --- a/drivers/hwtracing/coresight/of_coresight.c +++ b/drivers/hwtracing/coresight/of_coresight.c @@ -52,7 +52,19 @@ of_coresight_get_endpoint_device(struct device_node *endpoint) endpoint, of_dev_node_match); } -static void of_coresight_get_ports(const struct device_node *node, +static bool of_coresight_ep_is_input(struct device *dev, struct device_node *ep_node)
I suggested of_coresight_endpoint_get_port_id() in my review of 6/8. I'm good with either "ep" or "endpoint", as long as the names are consistent.
+{
- u32 dir;
- if (!of_property_read_u32(ep_node, "direction", &dir))
return dir == 0;
- dev_warn_once(dev, "Missing mandatory "direction" property!\n");
- return of_property_read_bool(ep_node, "slave-mode");
+}
+static void of_coresight_get_ports(struct device *dev,
const struct device_node *node, int *nr_inport, int *nr_outport)
{ struct device_node *ep = NULL; @@ -63,7 +75,7 @@ static void of_coresight_get_ports(const struct device_node *node, if (!ep) break;
if (of_property_read_bool(ep, "slave-mode"))
else out++;if (of_coresight_ep_is_input(dev, ep)) in++;
@@ -149,7 +161,7 @@ of_get_coresight_platform_data(struct device *dev, pdata->name = dev_name(dev); /* Get the number of input and output port for this component */
- of_coresight_get_ports(node, &pdata->nr_inport, &pdata->nr_outport);
- of_coresight_get_ports(dev, node, &pdata->nr_inport, &pdata->nr_outport);
if (pdata->nr_outport) { ret = of_coresight_alloc_memory(dev, pdata); @@ -168,7 +180,7 @@ of_get_coresight_platform_data(struct device *dev, * No need to deal with input ports, processing for as * processing for output ports will deal with them. */
if (of_find_property(ep, "slave-mode", NULL))
if (of_coresight_ep_is_input(dev, ep)) continue;
outport = of_graph_ep_coresight_get_port_id(dev, ep); -- 2.7.4
On 06/01/2018 09:39 PM, Mathieu Poirier wrote:
On Fri, Jun 01, 2018 at 02:16:06PM +0100, Suzuki K Poulose wrote:
So far we have relied on an undocumented property "slave-mode", to indicate if the given port is input or not. Since we are redefining the coresight bindings, define new property for the "direction" of data flow for a given connection endpoint in the device.
Each endpoint must define the following property.
- "direction" : 0 => Port is input 1 => Port is output
Cc: Mathieu Poirier mathieu.poirier@linaro.org Signed-off-by: Suzuki K Poulose suzuki.poulose@arm.com
drivers/hwtracing/coresight/of_coresight.c | 20 ++++++++++++++++----
You haven't documented the binding in bindings/arm/coresight.txt the same way you did with "coresight,hwid". I'm guessing you simply forgot to do a "git add" on the file when preparing the patchset.
1 file changed, 16 insertions(+), 4 deletions(-)
diff --git a/drivers/hwtracing/coresight/of_coresight.c b/drivers/hwtracing/coresight/of_coresight.c index 99d7a9c..63c1668 100644 --- a/drivers/hwtracing/coresight/of_coresight.c +++ b/drivers/hwtracing/coresight/of_coresight.c @@ -52,7 +52,19 @@ of_coresight_get_endpoint_device(struct device_node *endpoint) endpoint, of_dev_node_match); } -static void of_coresight_get_ports(const struct device_node *node, +static bool of_coresight_ep_is_input(struct device *dev, struct device_node *ep_node)
I suggested of_coresight_endpoint_get_port_id() in my review of 6/8. I'm good with either "ep" or "endpoint", as long as the names are consistent.
Yep, that's right. This is what I have for the documentation :
--- a/Documentation/devicetree/bindings/arm/coresight.txt +++ b/Documentation/devicetree/bindings/arm/coresight.txt @@ -103,9 +103,11 @@ with a specific direction of data flow, each connection must define the following properties to uniquely identify the connection details.
* Direction of the data flow w.r.t the component : - Each input port must have the following property defined at the "endpoint" + Each hardware port must have the following property defined at the "endpoint" for the port. - "slave-mode" + "direction" - 32bit integer, whose values are defined as follows : + 0 => the endpoint is an Input port + 1 => the endpoint is an Output port.
and changes to the examples as well..
Cheers Suzuki
Switch to updated coresight bindings for hw ports.
Cc: Sudeep Holla sudeep.holla@arm.com Cc: Liviu Dudau liviu.dudau@arm.com Cc: Mathieu Poirier mathieu.poirier@linaro.org Signed-off-by: Suzuki K Poulose suzuki.poulose@arm.com --- arch/arm64/boot/dts/arm/juno-base.dtsi | 82 +++++++++++++++++++++++++--------- arch/arm64/boot/dts/arm/juno.dts | 5 ++- 2 files changed, 63 insertions(+), 24 deletions(-)
diff --git a/arch/arm64/boot/dts/arm/juno-base.dtsi b/arch/arm64/boot/dts/arm/juno-base.dtsi index eb749c5..33b41ba 100644 --- a/arch/arm64/boot/dts/arm/juno-base.dtsi +++ b/arch/arm64/boot/dts/arm/juno-base.dtsi @@ -122,15 +122,18 @@ port@0 { reg = <0>; etf0_in_port: endpoint { - slave-mode; + direction = <0>; remote-endpoint = <&main_funnel_out_port>; + coresight,hwid = <0>; }; };
/* output port */ port@1 { - reg = <0>; + reg = <1>; etf0_out_port: endpoint { + coresight,hwid = <0>; + direction = <1>; }; }; }; @@ -145,8 +148,9 @@ power-domains = <&scpi_devpd 0>; port { tpiu_in_port: endpoint { - slave-mode; + direction = <0>; remote-endpoint = <&replicator_out_port0>; + coresight,hwid = <0>; }; }; }; @@ -168,23 +172,27 @@ reg = <0>; main_funnel_out_port: endpoint { remote-endpoint = <&etf0_in_port>; + coresight,hwid = <0>; + direction = <1>; }; };
/* input ports */ port@1 { - reg = <0>; + reg = <1>; main_funnel_in_port0: endpoint { - slave-mode; + direction = <0>; remote-endpoint = <&cluster0_funnel_out_port>; + coresight,hwid = <0>; }; };
port@2 { - reg = <1>; + reg = <2>; main_funnel_in_port1: endpoint { - slave-mode; + direction = <0>; remote-endpoint = <&cluster1_funnel_out_port>; + coresight,hwid = <1>; }; }; }; @@ -200,8 +208,9 @@ power-domains = <&scpi_devpd 0>; port { etr_in_port: endpoint { - slave-mode; + direction = <0>; remote-endpoint = <&replicator_out_port1>; + coresight,hwid = <0>; }; }; }; @@ -217,6 +226,8 @@ power-domains = <&scpi_devpd 0>; port { stm_out_port: endpoint { + coresight,hwid = <0>; + direction = <1>; }; }; }; @@ -240,6 +251,8 @@ port { cluster0_etm0_out_port: endpoint { remote-endpoint = <&cluster0_funnel_in_port0>; + coresight,hwid = <0>; + direction = <1>; }; }; }; @@ -259,22 +272,26 @@ reg = <0>; cluster0_funnel_out_port: endpoint { remote-endpoint = <&main_funnel_in_port0>; + coresight,hwid = <0>; + direction = <1>; }; };
port@1 { - reg = <0>; + reg = <1>; cluster0_funnel_in_port0: endpoint { - slave-mode; + direction = <0>; remote-endpoint = <&cluster0_etm0_out_port>; + coresight,hwid = <0>; }; };
port@2 { - reg = <1>; + reg = <2>; cluster0_funnel_in_port1: endpoint { - slave-mode; + direction = <0>; remote-endpoint = <&cluster0_etm1_out_port>; + coresight,hwid = <1>; }; }; }; @@ -299,6 +316,8 @@ port { cluster0_etm1_out_port: endpoint { remote-endpoint = <&cluster0_funnel_in_port1>; + coresight,hwid = <0>; + direction = <1>; }; }; }; @@ -322,6 +341,8 @@ port { cluster1_etm0_out_port: endpoint { remote-endpoint = <&cluster1_funnel_in_port0>; + coresight,hwid = <0>; + direction = <1>; }; }; }; @@ -341,36 +362,42 @@ reg = <0>; cluster1_funnel_out_port: endpoint { remote-endpoint = <&main_funnel_in_port1>; + coresight,hwid = <0>; + direction = <1>; }; };
port@1 { - reg = <0>; + reg = <1>; cluster1_funnel_in_port0: endpoint { - slave-mode; + direction = <0>; remote-endpoint = <&cluster1_etm0_out_port>; + coresight,hwid = <0>; }; };
port@2 { - reg = <1>; + reg = <2>; cluster1_funnel_in_port1: endpoint { - slave-mode; + direction = <0>; remote-endpoint = <&cluster1_etm1_out_port>; + coresight,hwid = <1>; }; }; port@3 { - reg = <2>; + reg = <3>; cluster1_funnel_in_port2: endpoint { - slave-mode; + direction = <0>; remote-endpoint = <&cluster1_etm2_out_port>; + coresight,hwid = <2>; }; }; port@4 { - reg = <3>; + reg = <4>; cluster1_funnel_in_port3: endpoint { - slave-mode; + direction = <0>; remote-endpoint = <&cluster1_etm3_out_port>; + coresight,hwid = <3>; }; }; }; @@ -395,6 +422,8 @@ port { cluster1_etm1_out_port: endpoint { remote-endpoint = <&cluster1_funnel_in_port1>; + coresight,hwid = <0>; + direction = <1>; }; }; }; @@ -418,6 +447,8 @@ port { cluster1_etm2_out_port: endpoint { remote-endpoint = <&cluster1_funnel_in_port2>; + coresight,hwid = <0>; + direction = <1>; }; }; }; @@ -441,6 +472,8 @@ port { cluster1_etm3_out_port: endpoint { remote-endpoint = <&cluster1_funnel_in_port3>; + coresight,hwid = <0>; + direction = <1>; }; }; }; @@ -462,6 +495,8 @@ reg = <0>; replicator_out_port0: endpoint { remote-endpoint = <&tpiu_in_port>; + coresight,hwid = <0>; + direction = <1>; }; };
@@ -469,14 +504,17 @@ reg = <1>; replicator_out_port1: endpoint { remote-endpoint = <&etr_in_port>; + coresight,hwid = <1>; + direction = <1>; }; };
/* replicator input port */ port@2 { - reg = <0>; + reg = <2>; replicator_in_port0: endpoint { - slave-mode; + direction = <0>; + coresight,hwid = <0>; }; }; }; diff --git a/arch/arm64/boot/dts/arm/juno.dts b/arch/arm64/boot/dts/arm/juno.dts index c9236c4..27b8036 100644 --- a/arch/arm64/boot/dts/arm/juno.dts +++ b/arch/arm64/boot/dts/arm/juno.dts @@ -260,10 +260,11 @@ &main_funnel { ports { port@3 { - reg = <2>; + reg = <3>; main_funnel_in_port2: endpoint { - slave-mode; + direction = <0>; remote-endpoint = <&stm_out_port>; + coresight,hwid = <2>; }; }; };
On Fri, Jun 01, 2018 at 02:16:07PM +0100, Suzuki K Poulose wrote:
Switch to updated coresight bindings for hw ports.
Cc: Sudeep Holla sudeep.holla@arm.com Cc: Liviu Dudau liviu.dudau@arm.com Cc: Mathieu Poirier mathieu.poirier@linaro.org Signed-off-by: Suzuki K Poulose suzuki.poulose@arm.com
Reviewed-and-tested-by: Mathieu Poirier mathieu.poirier@linaro.org
arch/arm64/boot/dts/arm/juno-base.dtsi | 82 +++++++++++++++++++++++++--------- arch/arm64/boot/dts/arm/juno.dts | 5 ++- 2 files changed, 63 insertions(+), 24 deletions(-)
diff --git a/arch/arm64/boot/dts/arm/juno-base.dtsi b/arch/arm64/boot/dts/arm/juno-base.dtsi index eb749c5..33b41ba 100644 --- a/arch/arm64/boot/dts/arm/juno-base.dtsi +++ b/arch/arm64/boot/dts/arm/juno-base.dtsi @@ -122,15 +122,18 @@ port@0 { reg = <0>; etf0_in_port: endpoint {
slave-mode;
direction = <0>; remote-endpoint = <&main_funnel_out_port>;
coresight,hwid = <0>; }; };
/* output port */ port@1 {
reg = <0>;
reg = <1>; etf0_out_port: endpoint {
coresight,hwid = <0>;
};direction = <1>; }; };
@@ -145,8 +148,9 @@ power-domains = <&scpi_devpd 0>; port { tpiu_in_port: endpoint {
slave-mode;
direction = <0>; remote-endpoint = <&replicator_out_port0>;
}; };coresight,hwid = <0>; };
@@ -168,23 +172,27 @@ reg = <0>; main_funnel_out_port: endpoint { remote-endpoint = <&etf0_in_port>;
coresight,hwid = <0>;
direction = <1>; }; };
/* input ports */ port@1 {
reg = <0>;
reg = <1>; main_funnel_in_port0: endpoint {
slave-mode;
direction = <0>; remote-endpoint = <&cluster0_funnel_out_port>;
coresight,hwid = <0>; }; };
port@2 {
reg = <1>;
reg = <2>; main_funnel_in_port1: endpoint {
slave-mode;
direction = <0>; remote-endpoint = <&cluster1_funnel_out_port>;
};coresight,hwid = <1>; }; };
@@ -200,8 +208,9 @@ power-domains = <&scpi_devpd 0>; port { etr_in_port: endpoint {
slave-mode;
direction = <0>; remote-endpoint = <&replicator_out_port1>;
}; };coresight,hwid = <0>; };
@@ -217,6 +226,8 @@ power-domains = <&scpi_devpd 0>; port { stm_out_port: endpoint {
coresight,hwid = <0>;
}; };direction = <1>; };
@@ -240,6 +251,8 @@ port { cluster0_etm0_out_port: endpoint { remote-endpoint = <&cluster0_funnel_in_port0>;
coresight,hwid = <0>;
}; };direction = <1>; };
@@ -259,22 +272,26 @@ reg = <0>; cluster0_funnel_out_port: endpoint { remote-endpoint = <&main_funnel_in_port0>;
coresight,hwid = <0>;
direction = <1>; }; };
port@1 {
reg = <0>;
reg = <1>; cluster0_funnel_in_port0: endpoint {
slave-mode;
direction = <0>; remote-endpoint = <&cluster0_etm0_out_port>;
coresight,hwid = <0>; }; };
port@2 {
reg = <1>;
reg = <2>; cluster0_funnel_in_port1: endpoint {
slave-mode;
direction = <0>; remote-endpoint = <&cluster0_etm1_out_port>;
};coresight,hwid = <1>; }; };
@@ -299,6 +316,8 @@ port { cluster0_etm1_out_port: endpoint { remote-endpoint = <&cluster0_funnel_in_port1>;
coresight,hwid = <0>;
}; };direction = <1>; };
@@ -322,6 +341,8 @@ port { cluster1_etm0_out_port: endpoint { remote-endpoint = <&cluster1_funnel_in_port0>;
coresight,hwid = <0>;
}; };direction = <1>; };
@@ -341,36 +362,42 @@ reg = <0>; cluster1_funnel_out_port: endpoint { remote-endpoint = <&main_funnel_in_port1>;
coresight,hwid = <0>;
direction = <1>; }; };
port@1 {
reg = <0>;
reg = <1>; cluster1_funnel_in_port0: endpoint {
slave-mode;
direction = <0>; remote-endpoint = <&cluster1_etm0_out_port>;
coresight,hwid = <0>; }; };
port@2 {
reg = <1>;
reg = <2>; cluster1_funnel_in_port1: endpoint {
slave-mode;
direction = <0>; remote-endpoint = <&cluster1_etm1_out_port>;
coresight,hwid = <1>; }; }; port@3 {
reg = <2>;
reg = <3>; cluster1_funnel_in_port2: endpoint {
slave-mode;
direction = <0>; remote-endpoint = <&cluster1_etm2_out_port>;
coresight,hwid = <2>; }; }; port@4 {
reg = <3>;
reg = <4>; cluster1_funnel_in_port3: endpoint {
slave-mode;
direction = <0>; remote-endpoint = <&cluster1_etm3_out_port>;
};coresight,hwid = <3>; }; };
@@ -395,6 +422,8 @@ port { cluster1_etm1_out_port: endpoint { remote-endpoint = <&cluster1_funnel_in_port1>;
coresight,hwid = <0>;
}; };direction = <1>; };
@@ -418,6 +447,8 @@ port { cluster1_etm2_out_port: endpoint { remote-endpoint = <&cluster1_funnel_in_port2>;
coresight,hwid = <0>;
}; };direction = <1>; };
@@ -441,6 +472,8 @@ port { cluster1_etm3_out_port: endpoint { remote-endpoint = <&cluster1_funnel_in_port3>;
coresight,hwid = <0>;
}; };direction = <1>; };
@@ -462,6 +495,8 @@ reg = <0>; replicator_out_port0: endpoint { remote-endpoint = <&tpiu_in_port>;
coresight,hwid = <0>;
direction = <1>; }; };
@@ -469,14 +504,17 @@ reg = <1>; replicator_out_port1: endpoint { remote-endpoint = <&etr_in_port>;
coresight,hwid = <1>;
direction = <1>; }; };
/* replicator input port */ port@2 {
reg = <0>;
reg = <2>; replicator_in_port0: endpoint {
slave-mode;
direction = <0>;
};coresight,hwid = <0>; }; };
diff --git a/arch/arm64/boot/dts/arm/juno.dts b/arch/arm64/boot/dts/arm/juno.dts index c9236c4..27b8036 100644 --- a/arch/arm64/boot/dts/arm/juno.dts +++ b/arch/arm64/boot/dts/arm/juno.dts @@ -260,10 +260,11 @@ &main_funnel { ports { port@3 {
reg = <2>;
reg = <3>; main_funnel_in_port2: endpoint {
slave-mode;
direction = <0>; remote-endpoint = <&stm_out_port>;
}; };coresight,hwid = <2>; };
-- 2.7.4
On Fri, Jun 01, 2018 at 02:15:59PM +0100, Suzuki K Poulose wrote:
Coresight uses DT graph bindings to describe the connections of the components. However we have some undocumented usage of the bindings to describe some of the properties of the connections.
The coresight driver needs to know the hardware ports invovled in the connection and the direction of data flow to effectively manage the trace sessions. So far we have relied on the "port" address (as described by the generic graph bindings) to represent the hardware port of the component for a connection.
The hardware uses separate numbering scheme for input and output ports, which implies, we could have two different (input and output) ports with the same port number. This could create problems in the graph bindings where the label of the port wouldn't match the address.
e.g, with the existing bindings we get :
port@0{ // Output port 0 reg = <0>; ... };
port@1{ reg = <0>; // Input port 0 endpoint { slave-mode; ... }; };
With the new enforcement in the DT rules, mismatches in label and address are not allowed (as see in the case for port@1). So, we need a new mechanism to describe the hardware port number reliably.
Also, we relied on an undocumented "slave-mode" property (see the above example) to indicate if the port is an input port. Let us formalise and switch to a new property to describe the direction of data flow.
There were three options considered for the hardware port number scheme:
- Use natural ordering in the DT to infer the hardware port number.
i.e, Mandate that the all ports are listed in the DT and in the ascending order for each class (input and output respectively). Pros : - We don't need new properties and if the existing DTS list them in order (which most of them do), they work out of the box. Cons : - We must list all the ports even if the system cannot/shouldn't use it. - It is prone to human errors (if the order is not kept).
- Use an explicit property to list both the direction and the hw port number and direction. Define "coresight,hwid" as 2 member array of u32, where the members are port number and the direction respectively.
e.g
port@0{ reg = <0>; endpoint { coresight,hwid = <0 1>; // Port # 0, Output } };
port@1{ reg = <1>; endpoint { coresight,hwid = <0 0>; // Port # 0, Input }; };
Pros: - The bindings are formal but not so reader friendly and could potentially lead to human errors. Cons: - Backward compatiblity is lost. 3) Use explicit properties (implemented in the series) for the hardware port id and direction. We define a new property "coresight,hwid" for each endpoint in coresight devices to specify the hardware port number explicitly. Also use a separate property "direction" to specify the direction of the data flow.
e.g,
port@0{ reg = <0>; endpoint { direction = <1>; // Output coresight,hwid = <0>; // Port # 0 } };
port@1{ reg = <1>; endpoint { direction = <0>; // Input coresight,hwid = <0>; // Port # 0 }; };
Pros: - The bindings are formal and reader friendly, and less prone to errors. Cons: - Backward compatibility is lost.
This series achieves implements Option (3) listed above while still retaining the backward compatibility. The driver now issues a warning (once) when it encounters the old bindings. It also cleans up the platform parsing code to reduce the memory usage by reusing the platform description. The series also includes the changes for Juno platform as an example. If there are no objections to the approach, I could post the series, converting all the in-kernel DTS to the new binding.
Suzuki K Poulose (8): dts: binding: coresight: Document graph bindings coresight: Fix remote endpoint parsing coresight: Cleanup platform description data coresight: platform: Cleanup coresight connection handling coresight: Handle errors in finding input/output ports dts: coresight: Clean up the device tree graph bindings dts: coresight: Define new bindings for direction of data flow dts: juno: Update coresight bindings for hw port
.../devicetree/bindings/arm/coresight.txt | 52 ++++++++-- arch/arm64/boot/dts/arm/juno-base.dtsi | 82 +++++++++++---- arch/arm64/boot/dts/arm/juno.dts | 5 +- drivers/hwtracing/coresight/coresight.c | 28 ++---- drivers/hwtracing/coresight/of_coresight.c | 111 ++++++++++++--------- include/linux/coresight.h | 11 +- 6 files changed, 181 insertions(+), 108 deletions(-)
Aside from the comments I've already posted I'm pretty much good with this set. Please rebase the next revision on my "next" branch and run checkpatch.pl on the set. Patch 6/8 and 7/8 are generating warnings.
Thanks, Mathieu
-- 2.7.4