[PATCH v3 21/26] coresight: etm4x: Use TRCDEVARCH for component discovery

From: Suzuki K Poulose
Date: Wed Oct 28 2020 - 18:11:15 EST


We have been using TRCIDR1 for detecting the ETM version. This
is in preparation for the future IP support.

Signed-off-by: Suzuki K Poulose <suzuki.poulose@xxxxxxx>
---
.../coresight/coresight-etm4x-core.c | 46 +++++++++----------
1 file changed, 23 insertions(+), 23 deletions(-)

diff --git a/drivers/hwtracing/coresight/coresight-etm4x-core.c b/drivers/hwtracing/coresight/coresight-etm4x-core.c
index 4ef47a2946a4..e36bc1c722c7 100644
--- a/drivers/hwtracing/coresight/coresight-etm4x-core.c
+++ b/drivers/hwtracing/coresight/coresight-etm4x-core.c
@@ -141,18 +141,6 @@ static void etm4_cs_unlock(struct etmv4_drvdata *drvdata,
CS_UNLOCK(csa->base);
}

-static bool etm4_arch_supported(u8 arch)
-{
- /* Mask out the minor version number */
- switch (arch & 0xf0) {
- case ETM_ARCH_V4:
- break;
- default:
- return false;
- }
- return true;
-}
-
static int etm4_cpu_id(struct coresight_device *csdev)
{
struct etmv4_drvdata *drvdata = dev_get_drvdata(csdev->dev.parent);
@@ -677,6 +665,26 @@ static const struct coresight_ops etm4_cs_ops = {
static bool etm_init_iomem_access(struct etmv4_drvdata *drvdata,
struct csdev_access *csa)
{
+ u32 devarch = readl_relaxed(drvdata->base + TRCDEVARCH);
+ u32 idr1 = readl_relaxed(drvdata->base + TRCIDR1);
+
+ /*
+ * All ETMs must implement TRCDEVARCH to indicate that
+ * the component is an ETMv4. To support any broken
+ * implementations we fall back to TRCIDR1 check, which
+ * is not really reliable.
+ */
+ if ((devarch & ETM_DEVARCH_ID_MASK) == ETM_DEVARCH_ETMv4x_ARCH) {
+ drvdata->arch = etm_devarch_to_arch(devarch);
+ } else {
+ pr_warn("CPU%d: ETM4x incompatible TRCDEVARCH: %x, falling back to TRCIDR1\n",
+ smp_processor_id(), devarch);
+
+ if (ETM_TRCIDR1_ARCH_MAJOR(idr1) != ETM_TRCIDR1_ARCH_ETMv4)
+ return false;
+ drvdata->arch = etm_trcidr_to_arch(idr1);
+ }
+
*csa = CSDEV_ACCESS_IOMEM(drvdata->base);
return true;
}
@@ -693,7 +701,6 @@ static bool etm_init_csdev_access(struct etmv4_drvdata *drvdata,
static void etm4_init_arch_data(void *info)
{
u32 etmidr0;
- u32 etmidr1;
u32 etmidr2;
u32 etmidr3;
u32 etmidr4;
@@ -758,14 +765,6 @@ static void etm4_init_arch_data(void *info)
/* TSSIZE, bits[28:24] Global timestamp size field */
drvdata->ts_size = BMVAL(etmidr0, 24, 28);

- /* base architecture of trace unit */
- etmidr1 = etm4x_relaxed_read32(csa, TRCIDR1);
- /*
- * TRCARCHMIN, bits[7:4] architecture the minor version number
- * TRCARCHMAJ, bits[11:8] architecture major versin number
- */
- drvdata->arch = BMVAL(etmidr1, 4, 11);
-
/* maximum size of resources */
etmidr2 = etm4x_relaxed_read32(csa, TRCIDR2);
/* CIDSIZE, bits[9:5] Indicates the Context ID size */
@@ -1602,7 +1601,7 @@ static int etm4_probe(struct amba_device *adev, const struct amba_id *id)
etm4_init_arch_data, &init_arg, 1))
dev_err(dev, "ETM arch init failed\n");

- if (etm4_arch_supported(drvdata->arch) == false)
+ if (!drvdata->arch)
return -EINVAL;

etm4_init_trace_id(drvdata);
@@ -1634,7 +1633,8 @@ static int etm4_probe(struct amba_device *adev, const struct amba_id *id)

pm_runtime_put(&adev->dev);
dev_info(&drvdata->csdev->dev, "CPU%d: ETM v%d.%d initialized\n",
- drvdata->cpu, drvdata->arch >> 4, drvdata->arch & 0xf);
+ drvdata->cpu, ETM_ARCH_MAJOR_VERSION(drvdata->arch),
+ ETM_ARCH_MINOR_VERSION(drvdata->arch));

if (boot_enable) {
coresight_enable(drvdata->csdev);
--
2.24.1