On Wed, May 01, 2019 at 09:49:35AM +0100, Mike Leach wrote:
The v8 architecture defines the relationship between a PE, its optional ETM and a CTI. Unlike non-architectural CTIs which are implementation defined, this has a fixed set of connections which can therefore be represented as a simple tag in the device tree.
This patch defines the tags needed to create an entry for this PE/ETM/CTI relationship, and provides functionality to implement the connection model in the CTI driver.
Signed-off-by: Mike Leach mike.leach@linaro.org
drivers/hwtracing/coresight/coresight-cti.c | 10 +- drivers/hwtracing/coresight/coresight-cti.h | 5 + .../hwtracing/coresight/of_coresight-cti.c | 179 +++++++++++++++++- 3 files changed, 188 insertions(+), 6 deletions(-)
diff --git a/drivers/hwtracing/coresight/coresight-cti.c b/drivers/hwtracing/coresight/coresight-cti.c index 06b1f84795a4..32d9bf0bf0b9 100644 --- a/drivers/hwtracing/coresight/coresight-cti.c +++ b/drivers/hwtracing/coresight/coresight-cti.c @@ -192,11 +192,11 @@ static void cti_set_default_config(struct cti_config *config)
- Add a connection entry to the list of connections for this
- CTI device.
*/ -static int cti_add_connection_entry(struct cti_drvdata *drvdata,
struct cti_trig_grp *in_info,
struct cti_trig_grp *out_info,
struct coresight_device *csdev,
const char *assoc_dev_name)
+int cti_add_connection_entry(struct cti_drvdata *drvdata,
struct cti_trig_grp *in_info,
struct cti_trig_grp *out_info,
struct coresight_device *csdev,
const char *assoc_dev_name)
{ struct cti_trig_con *tc; struct cti_device *cti_dev = &drvdata->ctidev; diff --git a/drivers/hwtracing/coresight/coresight-cti.h b/drivers/hwtracing/coresight/coresight-cti.h index a5bf59155f62..df40ca2d9548 100644 --- a/drivers/hwtracing/coresight/coresight-cti.h +++ b/drivers/hwtracing/coresight/coresight-cti.h @@ -234,6 +234,11 @@ enum cti_chan_set_op { extern const struct attribute_group *coresight_cti_groups[]; int cti_add_default_connection(struct cti_drvdata *drvdata); +int cti_add_connection_entry(struct cti_drvdata *drvdata,
struct cti_trig_grp *in_info,
struct cti_trig_grp *out_info,
struct coresight_device *csdev,
const char *assoc_dev_name);
int cti_enable(struct coresight_device *csdev, void *__unused); int cti_disable(struct coresight_device *csdev, void *__unused); void cti_write_all_hw_regs(struct cti_drvdata *drvdata); diff --git a/drivers/hwtracing/coresight/of_coresight-cti.c b/drivers/hwtracing/coresight/of_coresight-cti.c index 379ca1113deb..ee9a5906dc37 100644 --- a/drivers/hwtracing/coresight/of_coresight-cti.c +++ b/drivers/hwtracing/coresight/of_coresight-cti.c @@ -18,6 +18,16 @@ #include "coresight-cti.h" +/* Number of CTI signals in the v8 architecturally defined connection */ +#define NR_V8PE_IN_SIGS 2 +#define NR_V8PE_OUT_SIGS 3 +#define NR_V8ETM_INOUT_SIGS 4
+/* CTI device tree connection property keywords */ +#define CTI_DT_V8ARCH "arm,cti-v8-arch" +#define CTI_DT_CSDEV_ASSOC "arm,cs-dev-assoc" +#define CTI_DT_CTM_ID "arm,cti-ctm-id"
Quote from in the doc [1]:
3) The Documentation/ portion of the patch should come in the series before the code implementing the binding.
So please firstly give out the DT binding document patch before this patch in patch set.
[1] $KERNEL/Documentation/devicetree/bindings/submitting-patches.txt
#ifdef CONFIG_OF /* @@ -40,6 +50,166 @@ static int of_cti_get_cpu(const struct device_node *node) return (cpu < 0) ? -1 : cpu; } +/* match function to pass to find_device */ +static int of_dev_node_match(struct device *dev, void *data) +{
- return dev->of_node == data;
+}
+/*
- Find a registered coresight device from the device_node.
- The node info is associated with the AMBA parent, so we
- search this first to find a name, and use the name to find
- the device on the coresight bus as they are always named the same.
- */
+static struct coresight_device * +of_cti_get_assoc_cs_dev_by_node(struct device_node *node) +{
- struct device *dev, *adev;
- struct coresight_device *csdev = NULL;
- const char *amba_dev_name = NULL;
- if (!node)
return NULL;
- adev = bus_find_device(&amba_bustype, NULL, node, of_dev_node_match);
- if (adev) {
amba_dev_name = dev_name(adev);
dev = bus_find_device_by_name(&coresight_bustype, NULL,
amba_dev_name);
if (dev) {
csdev = to_coresight_device(dev);
put_device(dev);
}
put_device(adev);
- }
- return csdev;
+}
+/*
- Create an architecturally defined v8 connection
- must have a cpu, can have an ETM.
- */
+static int of_cti_create_v8_connections(struct cti_drvdata *drvdata,
struct device_node *np)
+{
- struct cti_device *cti_dev = &drvdata->ctidev;
- struct cti_trig_grp *in = 0, *out = 0, *etm_in = 0, *etm_out = 0;
- int cpuid = 0, i;
- struct device_node *cs_np;
- struct coresight_device *csdev = NULL;
- char cpu_name_str[16];
- const char *assoc_name = NULL;
- int *sig_in_types = 0, *sig_out_types = 0;
- int *etm_sig_in_types = 0, *etm_sig_out_types = 0;
- /* Must have a cpu node */
- cpuid = of_cti_get_cpu(np);
- if (cpuid < 0) {
dev_warn(drvdata->dev, "CTI v8 DT binding no cpu\n");
return -EINVAL;
- }
- cti_dev->cpu = cpuid;
- /* Can have an etm node */
- cs_np = of_parse_phandle(np, CTI_DT_CSDEV_ASSOC, 0);
For this patch, I have one main question: what's the relationship between one CTI with PE and ETM (optional)? Is it possible that CTI only connects to ETM but without PE?
And suggest this function can be divided into two sub functions:
of_cti_create_v8_pe_connections() of_cti_create_v8_etm_connections()
Thanks, Leo Yan
- /* Allocate the v8 cpu memory */
- in = kzalloc(sizeof(struct cti_trig_grp), GFP_KERNEL);
- if (!in)
goto of_create_v8_mem_err;
- out = kzalloc(sizeof(struct cti_trig_grp), GFP_KERNEL);
- if (!out)
goto of_create_v8_mem_err;
- sig_in_types = kzalloc(sizeof(int) * NR_V8PE_IN_SIGS, GFP_KERNEL);
- if (!sig_in_types)
goto of_create_v8_mem_err;
- sig_out_types = kzalloc(sizeof(int) * NR_V8PE_OUT_SIGS, GFP_KERNEL);
- if (!sig_out_types)
goto of_create_v8_mem_err;
- /* Allocate the ETM connection memory if required */
- if (cs_np) {
etm_in = kzalloc(sizeof(struct cti_trig_grp), GFP_KERNEL);
if (!etm_in)
goto of_create_v8_mem_err;
etm_out = kzalloc(sizeof(struct cti_trig_grp), GFP_KERNEL);
if (!etm_out)
goto of_create_v8_mem_err;
etm_sig_in_types =
kzalloc(sizeof(int) * NR_V8ETM_INOUT_SIGS, GFP_KERNEL);
if (!etm_sig_in_types)
goto of_create_v8_mem_err;
etm_sig_out_types =
kzalloc(sizeof(int) * NR_V8ETM_INOUT_SIGS, GFP_KERNEL);
if (!etm_sig_out_types)
goto of_create_v8_mem_err;
- }
- /* Create the v8 PE CTI connection */
- in->nr_sigs = NR_V8PE_IN_SIGS;
- in->used_mask = 0x3; /* sigs <0 1> */
- in->sig_types = sig_in_types;
- sig_in_types[0] = CTITRIG_PE_DBGTRIGGER;
- sig_in_types[1] = CTITRIG_PE_PMUIRQ;
- out->nr_sigs = NR_V8PE_OUT_SIGS;
- out->used_mask = 0x7; /* sigs <0 1 2 > */
- out->sig_types = sig_out_types;
- sig_out_types[0] = CTITRIG_PE_EDBGREQ;
- sig_out_types[1] = CTITRIG_PE_DBGRESTART;
- sig_out_types[2] = CTITRIG_PE_CTIIRQ;
- scnprintf(cpu_name_str, 16, "cpu%d", cpuid);
- cti_add_connection_entry(drvdata, in, out, NULL, cpu_name_str);
- /* filter pe_edbgreq */
- drvdata->config.trig_out_filter = 0x1;
- /* Create the v8 ETM associated connection */
- if (cs_np) {
etm_in->nr_sigs = NR_V8ETM_INOUT_SIGS;
etm_in->used_mask = 0xF0;
etm_in->sig_types = etm_sig_in_types;
etm_out->nr_sigs = NR_V8ETM_INOUT_SIGS;
etm_out->used_mask = 0xF0;
etm_out->sig_types = etm_sig_out_types;
for (i = 0; i < NR_V8ETM_INOUT_SIGS; i++) {
etm_sig_in_types[i] = CTITRIG_ETM_EXTOUT;
etm_sig_out_types[i] = CTITRIG_ETM_EXTIN;
}
csdev = of_cti_get_assoc_cs_dev_by_node(cs_np);
if (csdev)
assoc_name = dev_name(&csdev->dev);
else
assoc_name = cs_np->full_name;
cti_add_connection_entry(drvdata, etm_in, etm_out,
csdev, assoc_name);
of_node_put(cs_np);
- }
- return 0;
+of_create_v8_mem_err:
- kfree(in);
- kfree(out);
- kfree(sig_in_types);
- kfree(sig_out_types);
- if (cs_np) {
kfree(etm_in);
kfree(etm_out);
kfree(etm_sig_in_types);
kfree(etm_sig_out_types);
- }
- return -ENOMEM;
+}
/* get the hardware configuration & connection data. */ int of_cti_get_hw_data(struct device *dev, struct device_node *np, @@ -48,8 +218,15 @@ int of_cti_get_hw_data(struct device *dev, int rc = 0; struct cti_device *cti_dev = &drvdata->ctidev;
- /* get any CTM ID - defaults to 0 */
- of_property_read_u32(np, CTI_DT_CTM_ID, &cti_dev->ctm_id);
- /* check for a v8 architectural CTI device */
- if (of_property_read_bool(np, CTI_DT_V8ARCH))
rc = of_cti_create_v8_connections(drvdata, np);
- /* if no connections, just add a single default based on max IN-OUT */
- if (cti_dev->nr_trig_con == 0)
- if (!rc && (cti_dev->nr_trig_con == 0)) rc = cti_add_default_connection(drvdata); return rc;
}
2.20.1
CoreSight mailing list CoreSight@lists.linaro.org https://lists.linaro.org/mailman/listinfo/coresight