2023-03-27 05:06:24

by Anshuman Khandual

[permalink] [raw]
Subject: [PATCH V2 0/5] coresight: etm4x: Migrate ACPI AMBA devices to platform driver

CoreSight ETM4x devices could be accessed either via MMIO (handled via
amba_driver) or CPU system instructions (handled via platform driver). But
this has the following issues :

- Each new CPU comes up with its own PID and thus we need to keep on
adding the "known" PIDs to get it working with AMBA driver. While
the ETM4 architecture (and CoreSight architecture) defines way to
identify a device as ETM4. Thus older kernels won't be able to
"discover" a newer CPU, unless we add the PIDs.

- With ACPI, the ETM4x devices have the same HID to identify the device
irrespective of the mode of access. This creates a problem where two
different drivers (both AMBA based driver and platform driver) would
hook into the "HID" and could conflict. e.g., if AMBA driver gets
hold of a non-MMIO device, the probe fails. If we have single driver
hooked into the given "HID", we could handle them seamlessly,
irrespective of the mode of access.

- CoreSight is heavily dependent on the runtime power management. With
ACPI, amba_driver doesn't get us anywhere with handling the power
and thus one need to always turn the power ON to use them. Moving to
platform driver gives us the power management for free.

Due to all of the above, we are moving the MMIO based etm4x devices to be
supported via platform driver. The series makes the existing platform
driver generic to handle both type of the access modes. Although existing
AMBA driver would still continue to support DT based etm4x MMIO devices.

The series applies on 6.3-rc4.

Changes in V2:

- Enables ACPI etm4x device support in the existing platform driver
- Dropped last two patches from the series
- Dropped redundant 'devarch' checking from is_etm4x_device()
- Renamed updated is_etm4x_device() as is_etm4x_devtype()
- Fixed arguments in fallback stub for etm4_check_arch_features()
- Tagged etm4_dev_pm_ops with etm4_platform_driver
- Updated the comment for coresight_get_enable_apb_pclk() helper
- Updated the comment for new 'pclk' element in struct etm4_drvdata
- Dropped the clock when devm_ioremap_resource() fails
- Convert IS_ERR() into a direct pointer check in etm4_remove_platform_dev()
- Dropped "arm,coresight-etm4x" compatible property from etm4_match[]

Changes in V1:

https://lore.kernel.org/all/[email protected]/

Cc: Steve Clevenger <[email protected]>
Cc: Rob Herring <[email protected]>
Cc: Frank Rowand <[email protected]>
Cc: Russell King (Oracle) <[email protected]>
Cc: Greg Kroah-Hartman <[email protected]>
Cc: "Rafael J. Wysocki" <[email protected]>
Cc: Len Brown <[email protected]>
Cc: Sudeep Holla <[email protected]>
Cc: Lorenzo Pieralisi <[email protected]>
Cc: Mathieu Poirier <[email protected]>
Cc: Suzuki K Poulose <[email protected]>
Cc: Mike Leach <[email protected]>
Cc: Leo Yan <[email protected]>
Cc: [email protected]
Cc: [email protected]
Cc: [email protected]
Cc: [email protected]
Cc: [email protected]

Anshuman Khandual (4):
coresight: etm4x: Allocate and device assign 'struct etmv4_drvdata' earlier
coresight: etm4x: Drop iomem 'base' argument from etm4_probe()
coresight: etm4x: Drop pid argument from etm4_probe()
coresight: etm4x: Change etm4_platform_driver driver for MMIO devices

Suzuki Poulose (1):
coresight: etm4x: Add ACPI support in platform driver

drivers/acpi/acpi_amba.c | 1 -
.../coresight/coresight-etm4x-core.c | 114 ++++++++++++++----
drivers/hwtracing/coresight/coresight-etm4x.h | 4 +
include/linux/coresight.h | 59 +++++++++
4 files changed, 154 insertions(+), 24 deletions(-)

--
2.25.1


2023-03-27 05:06:50

by Anshuman Khandual

[permalink] [raw]
Subject: [PATCH V2 2/5] coresight: etm4x: Drop iomem 'base' argument from etm4_probe()

'struct etm4_drvdata' itself can carry the base address before etm4_probe()
gets called. Just drop that redundant argument from etm4_probe().

Cc: Mathieu Poirier <[email protected]>
Cc: Suzuki K Poulose <[email protected]>
Cc: Mike Leach <[email protected]>
Cc: Leo Yan <[email protected]>
Cc: [email protected]
Cc: [email protected]
Cc: [email protected]
Signed-off-by: Anshuman Khandual <[email protected]>
---
drivers/hwtracing/coresight/coresight-etm4x-core.c | 10 +++++-----
1 file changed, 5 insertions(+), 5 deletions(-)

diff --git a/drivers/hwtracing/coresight/coresight-etm4x-core.c b/drivers/hwtracing/coresight/coresight-etm4x-core.c
index 10119c223fbe..5d77571a8df9 100644
--- a/drivers/hwtracing/coresight/coresight-etm4x-core.c
+++ b/drivers/hwtracing/coresight/coresight-etm4x-core.c
@@ -2048,7 +2048,7 @@ static int etm4_add_coresight_dev(struct etm4_init_arg *init_arg)
return 0;
}

-static int etm4_probe(struct device *dev, void __iomem *base, u32 etm_pid)
+static int etm4_probe(struct device *dev, u32 etm_pid)
{
struct etmv4_drvdata *drvdata = dev_get_drvdata(dev);
struct csdev_access access = { 0 };
@@ -2069,8 +2069,6 @@ static int etm4_probe(struct device *dev, void __iomem *base, u32 etm_pid)
return -ENOMEM;
}

- drvdata->base = base;
-
spin_lock_init(&drvdata->spinlock);

drvdata->cpu = coresight_get_cpu(dev);
@@ -2124,8 +2122,9 @@ static int etm4_probe_amba(struct amba_device *adev, const struct amba_id *id)
if (!drvdata)
return -ENOMEM;

+ drvdata->base = base;
dev_set_drvdata(dev, drvdata);
- ret = etm4_probe(dev, base, id->id);
+ ret = etm4_probe(dev, id->id);
if (!ret)
pm_runtime_put(&adev->dev);

@@ -2141,6 +2140,7 @@ static int etm4_probe_platform_dev(struct platform_device *pdev)
if (!drvdata)
return -ENOMEM;

+ drvdata->base = NULL;
dev_set_drvdata(&pdev->dev, drvdata);
pm_runtime_get_noresume(&pdev->dev);
pm_runtime_set_active(&pdev->dev);
@@ -2151,7 +2151,7 @@ static int etm4_probe_platform_dev(struct platform_device *pdev)
* HW by reading appropriate registers on the HW
* and thus we could skip the PID.
*/
- ret = etm4_probe(&pdev->dev, NULL, 0);
+ ret = etm4_probe(&pdev->dev, 0);

pm_runtime_put(&pdev->dev);
return ret;
--
2.25.1

2023-03-27 05:07:16

by Anshuman Khandual

[permalink] [raw]
Subject: [PATCH V2 3/5] coresight: etm4x: Drop pid argument from etm4_probe()

Coresight device pid can be retrieved from its iomem base address, which is
stored in 'struct etm4x_drvdata'. This drops pid argument from etm4_probe()
and 'struct etm4_init_arg'. Instead etm4_check_arch_features() derives the
coresight device pid with a new helper coresight_get_pid(), right before it
is consumed in etm4_hisi_match_pid().

Cc: Mathieu Poirier <[email protected]>
Cc: Suzuki K Poulose <[email protected]>
Cc: Mike Leach <[email protected]>
Cc: Leo Yan <[email protected]>
Cc: [email protected]
Cc: [email protected]
Cc: [email protected]
Signed-off-by: Anshuman Khandual <[email protected]>
---
.../coresight/coresight-etm4x-core.c | 21 +++++++------------
include/linux/coresight.h | 12 +++++++++++
2 files changed, 20 insertions(+), 13 deletions(-)

diff --git a/drivers/hwtracing/coresight/coresight-etm4x-core.c b/drivers/hwtracing/coresight/coresight-etm4x-core.c
index 5d77571a8df9..3521838ab4fb 100644
--- a/drivers/hwtracing/coresight/coresight-etm4x-core.c
+++ b/drivers/hwtracing/coresight/coresight-etm4x-core.c
@@ -66,7 +66,6 @@ static u64 etm4_get_access_type(struct etmv4_config *config);
static enum cpuhp_state hp_online;

struct etm4_init_arg {
- unsigned int pid;
struct device *dev;
struct csdev_access *csa;
};
@@ -370,8 +369,10 @@ static void etm4_disable_arch_specific(struct etmv4_drvdata *drvdata)
}

static void etm4_check_arch_features(struct etmv4_drvdata *drvdata,
- unsigned int id)
+ struct csdev_access *csa)
{
+ unsigned int id = coresight_get_pid(csa);
+
if (etm4_hisi_match_pid(id))
set_bit(ETM4_IMPDEF_HISI_CORE_COMMIT, drvdata->arch_features);
}
@@ -385,7 +386,7 @@ static void etm4_disable_arch_specific(struct etmv4_drvdata *drvdata)
}

static void etm4_check_arch_features(struct etmv4_drvdata *drvdata,
- unsigned int id)
+ struct csdev_access *csa)
{
}
#endif /* CONFIG_ETM4X_IMPDEF_FEATURE */
@@ -1165,7 +1166,7 @@ static void etm4_init_arch_data(void *info)
etm4_os_unlock_csa(drvdata, csa);
etm4_cs_unlock(drvdata, csa);

- etm4_check_arch_features(drvdata, init_arg->pid);
+ etm4_check_arch_features(drvdata, csa);

/* find all capabilities of the tracing unit */
etmidr0 = etm4x_relaxed_read32(csa, TRCIDR0);
@@ -2048,7 +2049,7 @@ static int etm4_add_coresight_dev(struct etm4_init_arg *init_arg)
return 0;
}

-static int etm4_probe(struct device *dev, u32 etm_pid)
+static int etm4_probe(struct device *dev)
{
struct etmv4_drvdata *drvdata = dev_get_drvdata(dev);
struct csdev_access access = { 0 };
@@ -2077,7 +2078,6 @@ static int etm4_probe(struct device *dev, u32 etm_pid)

init_arg.dev = dev;
init_arg.csa = &access;
- init_arg.pid = etm_pid;

/*
* Serialize against CPUHP callbacks to avoid race condition
@@ -2124,7 +2124,7 @@ static int etm4_probe_amba(struct amba_device *adev, const struct amba_id *id)

drvdata->base = base;
dev_set_drvdata(dev, drvdata);
- ret = etm4_probe(dev, id->id);
+ ret = etm4_probe(dev);
if (!ret)
pm_runtime_put(&adev->dev);

@@ -2146,12 +2146,7 @@ static int etm4_probe_platform_dev(struct platform_device *pdev)
pm_runtime_set_active(&pdev->dev);
pm_runtime_enable(&pdev->dev);

- /*
- * System register based devices could match the
- * HW by reading appropriate registers on the HW
- * and thus we could skip the PID.
- */
- ret = etm4_probe(&pdev->dev, 0);
+ ret = etm4_probe(&pdev->dev);

pm_runtime_put(&pdev->dev);
return ret;
diff --git a/include/linux/coresight.h b/include/linux/coresight.h
index f19a47b9bb5a..f85b041ea475 100644
--- a/include/linux/coresight.h
+++ b/include/linux/coresight.h
@@ -370,6 +370,18 @@ static inline u32 csdev_access_relaxed_read32(struct csdev_access *csa,
return csa->read(offset, true, false);
}

+#define CORESIGHT_PIDRn(i) (0xFE0 + ((i) * 4))
+
+static inline u32 coresight_get_pid(struct csdev_access *csa)
+{
+ u32 i, pid = 0;
+
+ for (i = 0; i < 4; i++)
+ pid |= csdev_access_relaxed_read32(csa, CORESIGHT_PIDRn(i)) << (i * 8);
+
+ return pid;
+}
+
static inline u64 csdev_access_relaxed_read_pair(struct csdev_access *csa,
u32 lo_offset, u32 hi_offset)
{
--
2.25.1

2023-03-27 05:07:23

by Anshuman Khandual

[permalink] [raw]
Subject: [PATCH V2 1/5] coresight: etm4x: Allocate and device assign 'struct etmv4_drvdata' earlier

Allocate and device assign 'struct etmv4_drvdata' earlier during the driver
probe, ensuring that it can be retrieved in power management based runtime
callbacks if required. This will also help in dropping iomem base address
argument from the function etm4_probe() later.

Cc: Mathieu Poirier <[email protected]>
Cc: Suzuki K Poulose <[email protected]>
Cc: Mike Leach <[email protected]>
Cc: Leo Yan <[email protected]>
Cc: [email protected]
Cc: [email protected]
Cc: [email protected]
Signed-off-by: Anshuman Khandual <[email protected]>
---
.../coresight/coresight-etm4x-core.c | 19 ++++++++++++++-----
1 file changed, 14 insertions(+), 5 deletions(-)

diff --git a/drivers/hwtracing/coresight/coresight-etm4x-core.c b/drivers/hwtracing/coresight/coresight-etm4x-core.c
index 1ea8f173cca0..10119c223fbe 100644
--- a/drivers/hwtracing/coresight/coresight-etm4x-core.c
+++ b/drivers/hwtracing/coresight/coresight-etm4x-core.c
@@ -2050,17 +2050,14 @@ static int etm4_add_coresight_dev(struct etm4_init_arg *init_arg)

static int etm4_probe(struct device *dev, void __iomem *base, u32 etm_pid)
{
- struct etmv4_drvdata *drvdata;
+ struct etmv4_drvdata *drvdata = dev_get_drvdata(dev);
struct csdev_access access = { 0 };
struct etm4_init_arg init_arg = { 0 };
struct etm4_init_arg *delayed;

- drvdata = devm_kzalloc(dev, sizeof(*drvdata), GFP_KERNEL);
- if (!drvdata)
+ if (WARN_ON(!drvdata))
return -ENOMEM;

- dev_set_drvdata(dev, drvdata);
-
if (pm_save_enable == PARAM_PM_SAVE_FIRMWARE)
pm_save_enable = coresight_loses_context_with_cpu(dev) ?
PARAM_PM_SAVE_SELF_HOSTED : PARAM_PM_SAVE_NEVER;
@@ -2112,6 +2109,7 @@ static int etm4_probe(struct device *dev, void __iomem *base, u32 etm_pid)

static int etm4_probe_amba(struct amba_device *adev, const struct amba_id *id)
{
+ struct etmv4_drvdata *drvdata;
void __iomem *base;
struct device *dev = &adev->dev;
struct resource *res = &adev->res;
@@ -2122,6 +2120,11 @@ static int etm4_probe_amba(struct amba_device *adev, const struct amba_id *id)
if (IS_ERR(base))
return PTR_ERR(base);

+ drvdata = devm_kzalloc(dev, sizeof(*drvdata), GFP_KERNEL);
+ if (!drvdata)
+ return -ENOMEM;
+
+ dev_set_drvdata(dev, drvdata);
ret = etm4_probe(dev, base, id->id);
if (!ret)
pm_runtime_put(&adev->dev);
@@ -2131,8 +2134,14 @@ static int etm4_probe_amba(struct amba_device *adev, const struct amba_id *id)

static int etm4_probe_platform_dev(struct platform_device *pdev)
{
+ struct etmv4_drvdata *drvdata;
int ret;

+ drvdata = devm_kzalloc(&pdev->dev, sizeof(*drvdata), GFP_KERNEL);
+ if (!drvdata)
+ return -ENOMEM;
+
+ dev_set_drvdata(&pdev->dev, drvdata);
pm_runtime_get_noresume(&pdev->dev);
pm_runtime_set_active(&pdev->dev);
pm_runtime_enable(&pdev->dev);
--
2.25.1

2023-03-27 05:07:41

by Anshuman Khandual

[permalink] [raw]
Subject: [PATCH V2 5/5] coresight: etm4x: Add ACPI support in platform driver

From: Suzuki Poulose <[email protected]>

Drop ETM4X ACPI ID from the AMBA ACPI device list, and instead just move it
inside the new ACPI devices list detected and used via platform driver.

Cc: "Rafael J. Wysocki" <[email protected]>
Cc: Len Brown <[email protected]>
Cc: Mathieu Poirier <[email protected]>
Cc: Suzuki K Poulose <[email protected]>
Cc: Mike Leach <[email protected]>
Cc: Leo Yan <[email protected]>
Cc: Sudeep Holla <[email protected]>
Cc: Lorenzo Pieralisi <[email protected]>
Cc: [email protected]
Cc: [email protected]
Cc: [email protected]
Cc: [email protected]
Signed-off-by: Suzuki Poulose <[email protected]>
Signed-off-by: Anshuman Khandual <[email protected]>
---
drivers/acpi/acpi_amba.c | 1 -
drivers/hwtracing/coresight/coresight-etm4x-core.c | 10 ++++++++++
2 files changed, 10 insertions(+), 1 deletion(-)

diff --git a/drivers/acpi/acpi_amba.c b/drivers/acpi/acpi_amba.c
index f5b443ab01c2..099966cbac5a 100644
--- a/drivers/acpi/acpi_amba.c
+++ b/drivers/acpi/acpi_amba.c
@@ -22,7 +22,6 @@
static const struct acpi_device_id amba_id_list[] = {
{"ARMH0061", 0}, /* PL061 GPIO Device */
{"ARMH0330", 0}, /* ARM DMA Controller DMA-330 */
- {"ARMHC500", 0}, /* ARM CoreSight ETM4x */
{"ARMHC501", 0}, /* ARM CoreSight ETR */
{"ARMHC502", 0}, /* ARM CoreSight STM */
{"ARMHC503", 0}, /* ARM CoreSight Debug */
diff --git a/drivers/hwtracing/coresight/coresight-etm4x-core.c b/drivers/hwtracing/coresight/coresight-etm4x-core.c
index bef205023bbe..56f7c59eef80 100644
--- a/drivers/hwtracing/coresight/coresight-etm4x-core.c
+++ b/drivers/hwtracing/coresight/coresight-etm4x-core.c
@@ -3,6 +3,7 @@
* Copyright (c) 2014, The Linux Foundation. All rights reserved.
*/

+#include <linux/acpi.h>
#include <linux/bitops.h>
#include <linux/kernel.h>
#include <linux/moduleparam.h>
@@ -2343,12 +2344,21 @@ static const struct of_device_id etm4_match[] = {
{}
};

+#ifdef CONFIG_ACPI
+static const struct acpi_device_id etm4x_acpi_ids[] = {
+ {"ARMHC500", 0}, /* ARM CoreSight ETM4x */
+ {}
+};
+MODULE_DEVICE_TABLE(acpi, etm4x_acpi_ids);
+#endif
+
static struct platform_driver etm4_platform_driver = {
.probe = etm4_probe_platform_dev,
.remove = etm4_remove_platform_dev,
.driver = {
.name = "coresight-etm4x",
.of_match_table = etm4_match,
+ .acpi_match_table = ACPI_PTR(etm4x_acpi_ids),
.suppress_bind_attrs = true,
.pm = &etm4_dev_pm_ops,
},
--
2.25.1

2023-03-27 05:07:52

by Anshuman Khandual

[permalink] [raw]
Subject: [PATCH V2 4/5] coresight: etm4x: Change etm4_platform_driver driver for MMIO devices

Add support for handling MMIO based devices via platform driver. We need to
make sure that :

1) The APB clock, if present is enabled at probe and via runtime_pm ops
2) Use the ETM4x architecture or CoreSight architecture registers to
identify a device as CoreSight ETM4x, instead of relying a white list of
"Peripheral IDs"

The driver doesn't get to handle the devices yet, until we wire the ACPI
changes to move the devices to be handled via platform driver than the
etm4_amba driver.

Cc: Mathieu Poirier <[email protected]>
Cc: Suzuki K Poulose <[email protected]>
Cc: Mike Leach <[email protected]>
Cc: Leo Yan <[email protected]>
Cc: [email protected]
Cc: [email protected]
Cc: [email protected]
Signed-off-by: Anshuman Khandual <[email protected]>
---
.../coresight/coresight-etm4x-core.c | 62 +++++++++++++++++--
drivers/hwtracing/coresight/coresight-etm4x.h | 4 ++
include/linux/coresight.h | 47 ++++++++++++++
3 files changed, 109 insertions(+), 4 deletions(-)

diff --git a/drivers/hwtracing/coresight/coresight-etm4x-core.c b/drivers/hwtracing/coresight/coresight-etm4x-core.c
index 3521838ab4fb..bef205023bbe 100644
--- a/drivers/hwtracing/coresight/coresight-etm4x-core.c
+++ b/drivers/hwtracing/coresight/coresight-etm4x-core.c
@@ -30,6 +30,7 @@
#include <linux/platform_device.h>
#include <linux/pm_runtime.h>
#include <linux/property.h>
+#include <linux/clk/clk-conf.h>

#include <asm/barrier.h>
#include <asm/sections.h>
@@ -1067,12 +1068,22 @@ static bool etm4_init_sysreg_access(struct etmv4_drvdata *drvdata,
return true;
}

+static bool is_etm4x_devtype(void __iomem *base)
+{
+ u32 devtype = readl(base + TRCDEVTYPE);
+
+ return (devtype == ETM_DEVTYPE_ETMv4x_ARCH);
+}
+
static bool etm4_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);

+ if (!is_coresight_device(drvdata->base) || !is_etm4x_devtype(drvdata->base))
+ return false;
+
/*
* All ETMs must implement TRCDEVARCH to indicate that
* the component is an ETMv4. To support any broken
@@ -2133,6 +2144,7 @@ static int etm4_probe_amba(struct amba_device *adev, const struct amba_id *id)

static int etm4_probe_platform_dev(struct platform_device *pdev)
{
+ struct resource *res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
struct etmv4_drvdata *drvdata;
int ret;

@@ -2140,7 +2152,18 @@ static int etm4_probe_platform_dev(struct platform_device *pdev)
if (!drvdata)
return -ENOMEM;

- drvdata->base = NULL;
+ drvdata->pclk = coresight_get_enable_apb_pclk(&pdev->dev);
+ if (IS_ERR(drvdata->pclk))
+ return -ENODEV;
+
+ if (res) {
+ drvdata->base = devm_ioremap_resource(&pdev->dev, res);
+ if (IS_ERR(drvdata->base)) {
+ clk_put(drvdata->pclk);
+ return PTR_ERR(drvdata->base);
+ }
+ }
+
dev_set_drvdata(&pdev->dev, drvdata);
pm_runtime_get_noresume(&pdev->dev);
pm_runtime_set_active(&pdev->dev);
@@ -2186,7 +2209,7 @@ static struct amba_cs_uci_id uci_id_etm4[] = {
/* ETMv4 UCI data */
.devarch = ETM_DEVARCH_ETMv4x_ARCH,
.devarch_mask = ETM_DEVARCH_ID_MASK,
- .devtype = 0x00000013,
+ .devtype = ETM_DEVTYPE_ETMv4x_ARCH,
}
};

@@ -2244,6 +2267,10 @@ static int __exit etm4_remove_platform_dev(struct platform_device *pdev)

if (drvdata)
ret = etm4_remove_dev(drvdata);
+
+ if (drvdata->pclk)
+ clk_put(drvdata->pclk);
+
pm_runtime_disable(&pdev->dev);
return ret;
}
@@ -2284,7 +2311,33 @@ static struct amba_driver etm4x_amba_driver = {
.id_table = etm4_ids,
};

-static const struct of_device_id etm4_sysreg_match[] = {
+#ifdef CONFIG_PM
+static int etm4_runtime_suspend(struct device *dev)
+{
+ struct etmv4_drvdata *drvdata = dev_get_drvdata(dev);
+
+ if (!IS_ERR(drvdata->pclk))
+ clk_disable_unprepare(drvdata->pclk);
+
+ return 0;
+}
+
+static int etm4_runtime_resume(struct device *dev)
+{
+ struct etmv4_drvdata *drvdata = dev_get_drvdata(dev);
+
+ if (!IS_ERR(drvdata->pclk))
+ clk_prepare_enable(drvdata->pclk);
+
+ return 0;
+}
+#endif
+
+static const struct dev_pm_ops etm4_dev_pm_ops = {
+ SET_RUNTIME_PM_OPS(etm4_runtime_suspend, etm4_runtime_resume, NULL)
+};
+
+static const struct of_device_id etm4_match[] = {
{ .compatible = "arm,coresight-etm4x-sysreg" },
{ .compatible = "arm,embedded-trace-extension" },
{}
@@ -2295,8 +2348,9 @@ static struct platform_driver etm4_platform_driver = {
.remove = etm4_remove_platform_dev,
.driver = {
.name = "coresight-etm4x",
- .of_match_table = etm4_sysreg_match,
+ .of_match_table = etm4_match,
.suppress_bind_attrs = true,
+ .pm = &etm4_dev_pm_ops,
},
};

diff --git a/drivers/hwtracing/coresight/coresight-etm4x.h b/drivers/hwtracing/coresight/coresight-etm4x.h
index 434f4e95ee17..78dfe7949548 100644
--- a/drivers/hwtracing/coresight/coresight-etm4x.h
+++ b/drivers/hwtracing/coresight/coresight-etm4x.h
@@ -701,6 +701,8 @@
#define ETM_DEVARCH_ETE_ARCH \
(ETM_DEVARCH_ARCHITECT_ARM | ETM_DEVARCH_ARCHID_ETE | ETM_DEVARCH_PRESENT)

+#define ETM_DEVTYPE_ETMv4x_ARCH 0x00000013
+
#define TRCSTATR_IDLE_BIT 0
#define TRCSTATR_PMSTABLE_BIT 1
#define ETM_DEFAULT_ADDR_COMP 0
@@ -952,6 +954,7 @@ struct etmv4_save_state {

/**
* struct etm4_drvdata - specifics associated to an ETM component
+ * @pclk APB clock for this component
* @base: Memory mapped base address for this component.
* @csdev: Component vitals needed by the framework.
* @spinlock: Only one at a time pls.
@@ -1017,6 +1020,7 @@ struct etmv4_save_state {
* @arch_features: Bitmap of arch features of etmv4 devices.
*/
struct etmv4_drvdata {
+ struct clk *pclk;
void __iomem *base;
struct coresight_device *csdev;
spinlock_t spinlock;
diff --git a/include/linux/coresight.h b/include/linux/coresight.h
index f85b041ea475..be60a8b84c49 100644
--- a/include/linux/coresight.h
+++ b/include/linux/coresight.h
@@ -6,6 +6,8 @@
#ifndef _LINUX_CORESIGHT_H
#define _LINUX_CORESIGHT_H

+#include <linux/amba/bus.h>
+#include <linux/clk.h>
#include <linux/device.h>
#include <linux/io.h>
#include <linux/perf_event.h>
@@ -370,6 +372,51 @@ static inline u32 csdev_access_relaxed_read32(struct csdev_access *csa,
return csa->read(offset, true, false);
}

+#define CORESIGHT_CIDRn(i) (0xFF0 + ((i) * 4))
+
+static inline u32 coresight_get_cid(void __iomem *base)
+{
+ u32 i, cid = 0;
+
+ for (i = 0; i < 4; i++)
+ cid |= readl(base + CORESIGHT_CIDRn(i)) << (i * 8);
+
+ return cid;
+}
+
+static inline bool is_coresight_device(void __iomem *base)
+{
+ u32 cid = coresight_get_cid(base);
+
+ return cid == CORESIGHT_CID;
+}
+
+/*
+ * Attempt to find and enable "APB clock" for the given device
+ *
+ * Returns:
+ *
+ * clk - Clock is found and enabled
+ * NULL - clock is not found
+ * ERROR - Clock is found but failed to enable
+ */
+static inline struct clk *coresight_get_enable_apb_pclk(struct device *dev)
+{
+ struct clk *pclk;
+ int ret;
+
+ pclk = clk_get(dev, "apb_pclk");
+ if (IS_ERR(pclk))
+ return NULL;
+
+ ret = clk_prepare_enable(pclk);
+ if (ret) {
+ clk_put(pclk);
+ return ERR_PTR(ret);
+ }
+ return pclk;
+}
+
#define CORESIGHT_PIDRn(i) (0xFE0 + ((i) * 4))

static inline u32 coresight_get_pid(struct csdev_access *csa)
--
2.25.1

2023-03-27 09:35:06

by Sudeep Holla

[permalink] [raw]
Subject: Re: [PATCH V2 5/5] coresight: etm4x: Add ACPI support in platform driver

On Mon, Mar 27, 2023 at 10:35:37AM +0530, Anshuman Khandual wrote:
> From: Suzuki Poulose <[email protected]>
>
> Drop ETM4X ACPI ID from the AMBA ACPI device list, and instead just move it
> inside the new ACPI devices list detected and used via platform driver.
>
> Cc: "Rafael J. Wysocki" <[email protected]>
> Cc: Len Brown <[email protected]>
> Cc: Mathieu Poirier <[email protected]>
> Cc: Suzuki K Poulose <[email protected]>
> Cc: Mike Leach <[email protected]>
> Cc: Leo Yan <[email protected]>
> Cc: Sudeep Holla <[email protected]>

Reviewed-by: Sudeep Holla <[email protected]> (for ACPI specific changes)

--
Regards,
Sudeep

2023-03-27 14:55:30

by Suzuki K Poulose

[permalink] [raw]
Subject: Re: [PATCH V2 4/5] coresight: etm4x: Change etm4_platform_driver driver for MMIO devices

On 27/03/2023 06:05, Anshuman Khandual wrote:
> Add support for handling MMIO based devices via platform driver. We need to
> make sure that :
>
> 1) The APB clock, if present is enabled at probe and via runtime_pm ops
> 2) Use the ETM4x architecture or CoreSight architecture registers to
> identify a device as CoreSight ETM4x, instead of relying a white list of
> "Peripheral IDs"
>
> The driver doesn't get to handle the devices yet, until we wire the ACPI
> changes to move the devices to be handled via platform driver than the
> etm4_amba driver.
>
> Cc: Mathieu Poirier <[email protected]>
> Cc: Suzuki K Poulose <[email protected]>
> Cc: Mike Leach <[email protected]>
> Cc: Leo Yan <[email protected]>
> Cc: [email protected]
> Cc: [email protected]
> Cc: [email protected]
> Signed-off-by: Anshuman Khandual <[email protected]>
> ---
> .../coresight/coresight-etm4x-core.c | 62 +++++++++++++++++--
> drivers/hwtracing/coresight/coresight-etm4x.h | 4 ++
> include/linux/coresight.h | 47 ++++++++++++++
> 3 files changed, 109 insertions(+), 4 deletions(-)
>
> diff --git a/drivers/hwtracing/coresight/coresight-etm4x-core.c b/drivers/hwtracing/coresight/coresight-etm4x-core.c
> index 3521838ab4fb..bef205023bbe 100644
> --- a/drivers/hwtracing/coresight/coresight-etm4x-core.c
> +++ b/drivers/hwtracing/coresight/coresight-etm4x-core.c
> @@ -30,6 +30,7 @@
> #include <linux/platform_device.h>
> #include <linux/pm_runtime.h>
> #include <linux/property.h>
> +#include <linux/clk/clk-conf.h>
>
> #include <asm/barrier.h>
> #include <asm/sections.h>
> @@ -1067,12 +1068,22 @@ static bool etm4_init_sysreg_access(struct etmv4_drvdata *drvdata,
> return true;
> }
>
> +static bool is_etm4x_devtype(void __iomem *base)
> +{
> + u32 devtype = readl(base + TRCDEVTYPE);
> +
> + return (devtype == ETM_DEVTYPE_ETMv4x_ARCH);
> +}
> +
> static bool etm4_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);
>
> + if (!is_coresight_device(drvdata->base) || !is_etm4x_devtype(drvdata->base))
> + return false;
> +
> /*
> * All ETMs must implement TRCDEVARCH to indicate that
> * the component is an ETMv4. To support any broken
> @@ -2133,6 +2144,7 @@ static int etm4_probe_amba(struct amba_device *adev, const struct amba_id *id)
>
> static int etm4_probe_platform_dev(struct platform_device *pdev)
> {
> + struct resource *res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
> struct etmv4_drvdata *drvdata;
> int ret;
>
> @@ -2140,7 +2152,18 @@ static int etm4_probe_platform_dev(struct platform_device *pdev)
> if (!drvdata)
> return -ENOMEM;
>
> - drvdata->base = NULL;
> + drvdata->pclk = coresight_get_enable_apb_pclk(&pdev->dev);
> + if (IS_ERR(drvdata->pclk))
> + return -ENODEV;
> +
> + if (res) {
> + drvdata->base = devm_ioremap_resource(&pdev->dev, res);
> + if (IS_ERR(drvdata->base)) {
> + clk_put(drvdata->pclk);
> + return PTR_ERR(drvdata->base);
> + }
> + }
> +
> dev_set_drvdata(&pdev->dev, drvdata);
> pm_runtime_get_noresume(&pdev->dev);
> pm_runtime_set_active(&pdev->dev);
> @@ -2186,7 +2209,7 @@ static struct amba_cs_uci_id uci_id_etm4[] = {
> /* ETMv4 UCI data */
> .devarch = ETM_DEVARCH_ETMv4x_ARCH,
> .devarch_mask = ETM_DEVARCH_ID_MASK,
> - .devtype = 0x00000013,
> + .devtype = ETM_DEVTYPE_ETMv4x_ARCH,
> }
> };
>
> @@ -2244,6 +2267,10 @@ static int __exit etm4_remove_platform_dev(struct platform_device *pdev)
>
> if (drvdata)
> ret = etm4_remove_dev(drvdata);
> +
> + if (drvdata->pclk)
> + clk_put(drvdata->pclk);
> +
> pm_runtime_disable(&pdev->dev);
> return ret;
> }
> @@ -2284,7 +2311,33 @@ static struct amba_driver etm4x_amba_driver = {
> .id_table = etm4_ids,
> };
>
> -static const struct of_device_id etm4_sysreg_match[] = {
> +#ifdef CONFIG_PM
> +static int etm4_runtime_suspend(struct device *dev)
> +{
> + struct etmv4_drvdata *drvdata = dev_get_drvdata(dev);
> +
> + if (!IS_ERR(drvdata->pclk))
> + clk_disable_unprepare(drvdata->pclk);
> +
> + return 0;
> +}
> +
> +static int etm4_runtime_resume(struct device *dev)
> +{
> + struct etmv4_drvdata *drvdata = dev_get_drvdata(dev);
> +
> + if (!IS_ERR(drvdata->pclk))
> + clk_prepare_enable(drvdata->pclk);
> +
> + return 0;
> +}
> +#endif
> +
> +static const struct dev_pm_ops etm4_dev_pm_ops = {
> + SET_RUNTIME_PM_OPS(etm4_runtime_suspend, etm4_runtime_resume, NULL)
> +};
> +
> +static const struct of_device_id etm4_match[] = {
> { .compatible = "arm,coresight-etm4x-sysreg" },
> { .compatible = "arm,embedded-trace-extension" },
> {}
> @@ -2295,8 +2348,9 @@ static struct platform_driver etm4_platform_driver = {
> .remove = etm4_remove_platform_dev,
> .driver = {
> .name = "coresight-etm4x",
> - .of_match_table = etm4_sysreg_match,
> + .of_match_table = etm4_match,
> .suppress_bind_attrs = true,
> + .pm = &etm4_dev_pm_ops,
> },
> };
>
> diff --git a/drivers/hwtracing/coresight/coresight-etm4x.h b/drivers/hwtracing/coresight/coresight-etm4x.h
> index 434f4e95ee17..78dfe7949548 100644
> --- a/drivers/hwtracing/coresight/coresight-etm4x.h
> +++ b/drivers/hwtracing/coresight/coresight-etm4x.h
> @@ -701,6 +701,8 @@
> #define ETM_DEVARCH_ETE_ARCH \
> (ETM_DEVARCH_ARCHITECT_ARM | ETM_DEVARCH_ARCHID_ETE | ETM_DEVARCH_PRESENT)
>
> +#define ETM_DEVTYPE_ETMv4x_ARCH 0x00000013

This has nothing to do with ETMv4 ARCH. This indicates :

[3:0] == 0x3 -> Indicates CoreSight Source
[7:4] == 0x1 -> Generates PE trace

So, we could call it : CS_DEVTYPE_PE_TRACE, but not ETMv4x

Rest looks good to me.

Suzuki

2023-03-31 11:12:23

by Suzuki K Poulose

[permalink] [raw]
Subject: Re: [PATCH V2 3/5] coresight: etm4x: Drop pid argument from etm4_probe()

On 27/03/2023 06:05, Anshuman Khandual wrote:
> Coresight device pid can be retrieved from its iomem base address, which is
> stored in 'struct etm4x_drvdata'. This drops pid argument from etm4_probe()
> and 'struct etm4_init_arg'. Instead etm4_check_arch_features() derives the
> coresight device pid with a new helper coresight_get_pid(), right before it
> is consumed in etm4_hisi_match_pid().
>
> Cc: Mathieu Poirier <[email protected]>
> Cc: Suzuki K Poulose <[email protected]>
> Cc: Mike Leach <[email protected]>
> Cc: Leo Yan <[email protected]>
> Cc: [email protected]
> Cc: [email protected]
> Cc: [email protected]
> Signed-off-by: Anshuman Khandual <[email protected]>
> ---
> .../coresight/coresight-etm4x-core.c | 21 +++++++------------
> include/linux/coresight.h | 12 +++++++++++
> 2 files changed, 20 insertions(+), 13 deletions(-)
>
> diff --git a/drivers/hwtracing/coresight/coresight-etm4x-core.c b/drivers/hwtracing/coresight/coresight-etm4x-core.c
> index 5d77571a8df9..3521838ab4fb 100644
> --- a/drivers/hwtracing/coresight/coresight-etm4x-core.c
> +++ b/drivers/hwtracing/coresight/coresight-etm4x-core.c
> @@ -66,7 +66,6 @@ static u64 etm4_get_access_type(struct etmv4_config *config);
> static enum cpuhp_state hp_online;
>
> struct etm4_init_arg {
> - unsigned int pid;
> struct device *dev;
> struct csdev_access *csa;
> };
> @@ -370,8 +369,10 @@ static void etm4_disable_arch_specific(struct etmv4_drvdata *drvdata)
> }
>
> static void etm4_check_arch_features(struct etmv4_drvdata *drvdata,
> - unsigned int id)
> + struct csdev_access *csa)
> {
> + unsigned int id = coresight_get_pid(csa);
> +

This throws up the following error on an ETE.

ete: trying to read unsupported register @fe0

So, I guess this must be performed only for iomem based
devices. System instruction based device must be identified
by MIDR_EL1/REVIDR_EL1 if needed for specific erratum.
This is not required now. So, we could bail out early
if we are system instruction based device.


> if (etm4_hisi_match_pid(id))
> set_bit(ETM4_IMPDEF_HISI_CORE_COMMIT, drvdata->arch_features);
> }
> @@ -385,7 +386,7 @@ static void etm4_disable_arch_specific(struct etmv4_drvdata *drvdata)
> }
>
> static void etm4_check_arch_features(struct etmv4_drvdata *drvdata,
> - unsigned int id)
> + struct csdev_access *csa)
> {
> }
> #endif /* CONFIG_ETM4X_IMPDEF_FEATURE */
> @@ -1165,7 +1166,7 @@ static void etm4_init_arch_data(void *info)
> etm4_os_unlock_csa(drvdata, csa);
> etm4_cs_unlock(drvdata, csa);
>
> - etm4_check_arch_features(drvdata, init_arg->pid);
> + etm4_check_arch_features(drvdata, csa);
>
> /* find all capabilities of the tracing unit */
> etmidr0 = etm4x_relaxed_read32(csa, TRCIDR0);
> @@ -2048,7 +2049,7 @@ static int etm4_add_coresight_dev(struct etm4_init_arg *init_arg)
> return 0;
> }
>
> -static int etm4_probe(struct device *dev, u32 etm_pid)
> +static int etm4_probe(struct device *dev)
> {
> struct etmv4_drvdata *drvdata = dev_get_drvdata(dev);
> struct csdev_access access = { 0 };
> @@ -2077,7 +2078,6 @@ static int etm4_probe(struct device *dev, u32 etm_pid)
>
> init_arg.dev = dev;
> init_arg.csa = &access;
> - init_arg.pid = etm_pid;
>
> /*
> * Serialize against CPUHP callbacks to avoid race condition
> @@ -2124,7 +2124,7 @@ static int etm4_probe_amba(struct amba_device *adev, const struct amba_id *id)
>
> drvdata->base = base;
> dev_set_drvdata(dev, drvdata);
> - ret = etm4_probe(dev, id->id);
> + ret = etm4_probe(dev);
> if (!ret)
> pm_runtime_put(&adev->dev);
>
> @@ -2146,12 +2146,7 @@ static int etm4_probe_platform_dev(struct platform_device *pdev)
> pm_runtime_set_active(&pdev->dev);
> pm_runtime_enable(&pdev->dev);
>
> - /*
> - * System register based devices could match the
> - * HW by reading appropriate registers on the HW
> - * and thus we could skip the PID.
> - */
> - ret = etm4_probe(&pdev->dev, 0);
> + ret = etm4_probe(&pdev->dev);
>
> pm_runtime_put(&pdev->dev);
> return ret;
> diff --git a/include/linux/coresight.h b/include/linux/coresight.h
> index f19a47b9bb5a..f85b041ea475 100644
> --- a/include/linux/coresight.h
> +++ b/include/linux/coresight.h
> @@ -370,6 +370,18 @@ static inline u32 csdev_access_relaxed_read32(struct csdev_access *csa,
> return csa->read(offset, true, false);
> }
>
> +#define CORESIGHT_PIDRn(i) (0xFE0 + ((i) * 4))
> +
> +static inline u32 coresight_get_pid(struct csdev_access *csa)
> +{
> + u32 i, pid = 0;
> +
> + for (i = 0; i < 4; i++)
> + pid |= csdev_access_relaxed_read32(csa, CORESIGHT_PIDRn(i)) << (i * 8);

Given the above, we could make this iomem specific.

Suzuki


> +
> + return pid;
> +}
> +
> static inline u64 csdev_access_relaxed_read_pair(struct csdev_access *csa,
> u32 lo_offset, u32 hi_offset)
> {

2023-03-31 21:28:32

by Steve Clevenger

[permalink] [raw]
Subject: Re: [PATCH V2 3/5] coresight: etm4x: Drop pid argument from etm4_probe()



On 3/31/2023 4:06 AM, Suzuki K Poulose wrote:
> On 27/03/2023 06:05, Anshuman Khandual wrote:
>> Coresight device pid can be retrieved from its iomem base address,
>> which is
>> stored in 'struct etm4x_drvdata'. This drops pid argument from
>> etm4_probe()
>> and 'struct etm4_init_arg'. Instead etm4_check_arch_features() derives
>> the
>> coresight device pid with a new helper coresight_get_pid(), right
>> before it
>> is consumed in etm4_hisi_match_pid().
>>
>> Cc: Mathieu Poirier <[email protected]>
>> Cc: Suzuki K Poulose <[email protected]>
>> Cc: Mike Leach <[email protected]>
>> Cc: Leo Yan <[email protected]>
>> Cc: [email protected]
>> Cc: [email protected]
>> Cc: [email protected]
>> Signed-off-by: Anshuman Khandual <[email protected]>
>> ---
>>   .../coresight/coresight-etm4x-core.c          | 21 +++++++------------
>>   include/linux/coresight.h                     | 12 +++++++++++
>>   2 files changed, 20 insertions(+), 13 deletions(-)
>>
>> diff --git a/drivers/hwtracing/coresight/coresight-etm4x-core.c
>> b/drivers/hwtracing/coresight/coresight-etm4x-core.c
>> index 5d77571a8df9..3521838ab4fb 100644
>> --- a/drivers/hwtracing/coresight/coresight-etm4x-core.c
>> +++ b/drivers/hwtracing/coresight/coresight-etm4x-core.c
>> @@ -66,7 +66,6 @@ static u64 etm4_get_access_type(struct etmv4_config
>> *config);
>>   static enum cpuhp_state hp_online;
>>     struct etm4_init_arg {
>> -    unsigned int        pid;
>>       struct device        *dev;
>>       struct csdev_access    *csa;
>>   };
>> @@ -370,8 +369,10 @@ static void etm4_disable_arch_specific(struct
>> etmv4_drvdata *drvdata)
>>   }
>>     static void etm4_check_arch_features(struct etmv4_drvdata *drvdata,
>> -                      unsigned int id)
>> +                     struct csdev_access *csa)
>>   {
>> +    unsigned int id = coresight_get_pid(csa);
>> +
>
> This throws up the following error on an ETE.
>
> ete: trying to read unsupported register @fe0
>
> So, I guess this must be performed only for iomem based
> devices. System instruction based device must be identified
> by MIDR_EL1/REVIDR_EL1 if needed for specific erratum.
> This is not required now. So, we could bail out early
> if we are system instruction based device.

Besides this, the PID is limited to (I think) 4 bits of ID. TRCIDRs
offer revision information, but nothing manufacturer specific save for
the designer. Register fields like MIDR_EL1 Variant + PartNum + Revision
and TRCPIDR3 REVAND offer help. It may be a combination of registers are
needed for a manufacturer to adequately ID a part to apply an erratum.
Perhaps you could at least cache MIDR_EL1 for possible future use?

>
>
>>       if (etm4_hisi_match_pid(id))
>>           set_bit(ETM4_IMPDEF_HISI_CORE_COMMIT, drvdata->arch_features);
>>   }
>> @@ -385,7 +386,7 @@ static void etm4_disable_arch_specific(struct
>> etmv4_drvdata *drvdata)
>>   }
>>     static void etm4_check_arch_features(struct etmv4_drvdata *drvdata,
>> -                     unsigned int id)
>> +                     struct csdev_access *csa)
>>   {
>>   }
>>   #endif /* CONFIG_ETM4X_IMPDEF_FEATURE */
>> @@ -1165,7 +1166,7 @@ static void etm4_init_arch_data(void *info)
>>       etm4_os_unlock_csa(drvdata, csa);
>>       etm4_cs_unlock(drvdata, csa);
>>   -    etm4_check_arch_features(drvdata, init_arg->pid);
>> +    etm4_check_arch_features(drvdata, csa);
>>         /* find all capabilities of the tracing unit */
>>       etmidr0 = etm4x_relaxed_read32(csa, TRCIDR0);
>> @@ -2048,7 +2049,7 @@ static int etm4_add_coresight_dev(struct
>> etm4_init_arg *init_arg)
>>       return 0;
>>   }
>>   -static int etm4_probe(struct device *dev, u32 etm_pid)
>> +static int etm4_probe(struct device *dev)
>>   {
>>       struct etmv4_drvdata *drvdata = dev_get_drvdata(dev);
>>       struct csdev_access access = { 0 };
>> @@ -2077,7 +2078,6 @@ static int etm4_probe(struct device *dev, u32
>> etm_pid)
>>         init_arg.dev = dev;
>>       init_arg.csa = &access;
>> -    init_arg.pid = etm_pid;
>>         /*
>>        * Serialize against CPUHP callbacks to avoid race condition
>> @@ -2124,7 +2124,7 @@ static int etm4_probe_amba(struct amba_device
>> *adev, const struct amba_id *id)
>>         drvdata->base = base;
>>       dev_set_drvdata(dev, drvdata);
>> -    ret = etm4_probe(dev, id->id);
>> +    ret = etm4_probe(dev);
>>       if (!ret)
>>           pm_runtime_put(&adev->dev);
>>   @@ -2146,12 +2146,7 @@ static int etm4_probe_platform_dev(struct
>> platform_device *pdev)
>>       pm_runtime_set_active(&pdev->dev);
>>       pm_runtime_enable(&pdev->dev);
>>   -    /*
>> -     * System register based devices could match the
>> -     * HW by reading appropriate registers on the HW
>> -     * and thus we could skip the PID.
>> -     */
>> -    ret = etm4_probe(&pdev->dev, 0);
>> +    ret = etm4_probe(&pdev->dev);
>>         pm_runtime_put(&pdev->dev);
>>       return ret;
>> diff --git a/include/linux/coresight.h b/include/linux/coresight.h
>> index f19a47b9bb5a..f85b041ea475 100644
>> --- a/include/linux/coresight.h
>> +++ b/include/linux/coresight.h
>> @@ -370,6 +370,18 @@ static inline u32
>> csdev_access_relaxed_read32(struct csdev_access *csa,
>>       return csa->read(offset, true, false);
>>   }
>>   +#define CORESIGHT_PIDRn(i)    (0xFE0 + ((i) * 4))
>> +
>> +static inline u32 coresight_get_pid(struct csdev_access *csa)
>> +{
>> +    u32 i, pid = 0;
>> +
>> +    for (i = 0; i < 4; i++)
>> +        pid |= csdev_access_relaxed_read32(csa, CORESIGHT_PIDRn(i))
>> << (i * 8);
>
> Given the above, we could make this iomem specific.
>
> Suzuki
>
>
>> +
>> +    return pid;
>> +}
>> +
>>   static inline u64 csdev_access_relaxed_read_pair(struct csdev_access
>> *csa,
>>                            u32 lo_offset, u32 hi_offset)
>>   {
>

2023-04-01 09:58:08

by Suzuki K Poulose

[permalink] [raw]
Subject: Re: [PATCH V2 3/5] coresight: etm4x: Drop pid argument from etm4_probe()

On 31/03/2023 22:24, Steve Clevenger wrote:
>
>
> On 3/31/2023 4:06 AM, Suzuki K Poulose wrote:
>> On 27/03/2023 06:05, Anshuman Khandual wrote:
>>> Coresight device pid can be retrieved from its iomem base address,
>>> which is
>>> stored in 'struct etm4x_drvdata'. This drops pid argument from
>>> etm4_probe()
>>> and 'struct etm4_init_arg'. Instead etm4_check_arch_features() derives
>>> the
>>> coresight device pid with a new helper coresight_get_pid(), right
>>> before it
>>> is consumed in etm4_hisi_match_pid().
>>>
>>> Cc: Mathieu Poirier <[email protected]>
>>> Cc: Suzuki K Poulose <[email protected]>
>>> Cc: Mike Leach <[email protected]>
>>> Cc: Leo Yan <[email protected]>
>>> Cc: [email protected]
>>> Cc: [email protected]
>>> Cc: [email protected]
>>> Signed-off-by: Anshuman Khandual <[email protected]>
>>> ---
>>>   .../coresight/coresight-etm4x-core.c          | 21 +++++++------------
>>>   include/linux/coresight.h                     | 12 +++++++++++
>>>   2 files changed, 20 insertions(+), 13 deletions(-)
>>>
>>> diff --git a/drivers/hwtracing/coresight/coresight-etm4x-core.c
>>> b/drivers/hwtracing/coresight/coresight-etm4x-core.c
>>> index 5d77571a8df9..3521838ab4fb 100644
>>> --- a/drivers/hwtracing/coresight/coresight-etm4x-core.c
>>> +++ b/drivers/hwtracing/coresight/coresight-etm4x-core.c
>>> @@ -66,7 +66,6 @@ static u64 etm4_get_access_type(struct etmv4_config
>>> *config);
>>>   static enum cpuhp_state hp_online;
>>>     struct etm4_init_arg {
>>> -    unsigned int        pid;
>>>       struct device        *dev;
>>>       struct csdev_access    *csa;
>>>   };
>>> @@ -370,8 +369,10 @@ static void etm4_disable_arch_specific(struct
>>> etmv4_drvdata *drvdata)
>>>   }
>>>     static void etm4_check_arch_features(struct etmv4_drvdata *drvdata,
>>> -                      unsigned int id)
>>> +                     struct csdev_access *csa)
>>>   {
>>> +    unsigned int id = coresight_get_pid(csa);
>>> +
>>
>> This throws up the following error on an ETE.
>>
>> ete: trying to read unsupported register @fe0
>>
>> So, I guess this must be performed only for iomem based
>> devices. System instruction based device must be identified
>> by MIDR_EL1/REVIDR_EL1 if needed for specific erratum.
>> This is not required now. So, we could bail out early
>> if we are system instruction based device.
>
> Besides this, the PID is limited to (I think) 4 bits of ID. TRCIDRs
> offer revision information, but nothing manufacturer specific save for
> the designer. Register fields like MIDR_EL1 Variant + PartNum + Revision
> and TRCPIDR3 REVAND offer help. It may be a combination of registers are
> needed for a manufacturer to adequately ID a part to apply an erratum.
> Perhaps you could at least cache MIDR_EL1 for possible future use?

Like I said, if we ever need them, we could add it. I don't see a point
in storing it right now, if we don't use it.

Suzuki

2023-04-04 15:33:40

by James Clark

[permalink] [raw]
Subject: Re: [PATCH V2 2/5] coresight: etm4x: Drop iomem 'base' argument from etm4_probe()



On 27/03/2023 06:05, Anshuman Khandual wrote:
> 'struct etm4_drvdata' itself can carry the base address before etm4_probe()
> gets called. Just drop that redundant argument from etm4_probe().
>
> Cc: Mathieu Poirier <[email protected]>
> Cc: Suzuki K Poulose <[email protected]>
> Cc: Mike Leach <[email protected]>
> Cc: Leo Yan <[email protected]>
> Cc: [email protected]
> Cc: [email protected]
> Cc: [email protected]
> Signed-off-by: Anshuman Khandual <[email protected]>
> ---
> drivers/hwtracing/coresight/coresight-etm4x-core.c | 10 +++++-----
> 1 file changed, 5 insertions(+), 5 deletions(-)
>
> diff --git a/drivers/hwtracing/coresight/coresight-etm4x-core.c b/drivers/hwtracing/coresight/coresight-etm4x-core.c
> index 10119c223fbe..5d77571a8df9 100644
> --- a/drivers/hwtracing/coresight/coresight-etm4x-core.c
> +++ b/drivers/hwtracing/coresight/coresight-etm4x-core.c
> @@ -2048,7 +2048,7 @@ static int etm4_add_coresight_dev(struct etm4_init_arg *init_arg)
> return 0;
> }
>
> -static int etm4_probe(struct device *dev, void __iomem *base, u32 etm_pid)
> +static int etm4_probe(struct device *dev, u32 etm_pid)
> {
> struct etmv4_drvdata *drvdata = dev_get_drvdata(dev);
> struct csdev_access access = { 0 };
> @@ -2069,8 +2069,6 @@ static int etm4_probe(struct device *dev, void __iomem *base, u32 etm_pid)
> return -ENOMEM;
> }
>
> - drvdata->base = base;
> -
> spin_lock_init(&drvdata->spinlock);
>
> drvdata->cpu = coresight_get_cpu(dev);
> @@ -2124,8 +2122,9 @@ static int etm4_probe_amba(struct amba_device *adev, const struct amba_id *id)
> if (!drvdata)
> return -ENOMEM;
>
> + drvdata->base = base;
> dev_set_drvdata(dev, drvdata);
> - ret = etm4_probe(dev, base, id->id);
> + ret = etm4_probe(dev, id->id);
> if (!ret)
> pm_runtime_put(&adev->dev);
>
> @@ -2141,6 +2140,7 @@ static int etm4_probe_platform_dev(struct platform_device *pdev)
> if (!drvdata)
> return -ENOMEM;
>
> + drvdata->base = NULL;

Very minor point, drvdata is zero alloced so it doesn't make sense to
zero this field but not the others. It's harmless, but it might imply
something and confuse someone.

Either way:
Reviewed-by: James Clark <[email protected]>

> dev_set_drvdata(&pdev->dev, drvdata);
> pm_runtime_get_noresume(&pdev->dev);
> pm_runtime_set_active(&pdev->dev);
> @@ -2151,7 +2151,7 @@ static int etm4_probe_platform_dev(struct platform_device *pdev)
> * HW by reading appropriate registers on the HW
> * and thus we could skip the PID.
> */
> - ret = etm4_probe(&pdev->dev, NULL, 0);
> + ret = etm4_probe(&pdev->dev, 0);
>
> pm_runtime_put(&pdev->dev);
> return ret;

2023-05-16 11:22:50

by Anshuman Khandual

[permalink] [raw]
Subject: Re: [PATCH V2 2/5] coresight: etm4x: Drop iomem 'base' argument from etm4_probe()



On 4/4/23 20:52, James Clark wrote:
>
> On 27/03/2023 06:05, Anshuman Khandual wrote:
>> 'struct etm4_drvdata' itself can carry the base address before etm4_probe()
>> gets called. Just drop that redundant argument from etm4_probe().
>>
>> Cc: Mathieu Poirier <[email protected]>
>> Cc: Suzuki K Poulose <[email protected]>
>> Cc: Mike Leach <[email protected]>
>> Cc: Leo Yan <[email protected]>
>> Cc: [email protected]
>> Cc: [email protected]
>> Cc: [email protected]
>> Signed-off-by: Anshuman Khandual <[email protected]>
>> ---
>> drivers/hwtracing/coresight/coresight-etm4x-core.c | 10 +++++-----
>> 1 file changed, 5 insertions(+), 5 deletions(-)
>>
>> diff --git a/drivers/hwtracing/coresight/coresight-etm4x-core.c b/drivers/hwtracing/coresight/coresight-etm4x-core.c
>> index 10119c223fbe..5d77571a8df9 100644
>> --- a/drivers/hwtracing/coresight/coresight-etm4x-core.c
>> +++ b/drivers/hwtracing/coresight/coresight-etm4x-core.c
>> @@ -2048,7 +2048,7 @@ static int etm4_add_coresight_dev(struct etm4_init_arg *init_arg)
>> return 0;
>> }
>>
>> -static int etm4_probe(struct device *dev, void __iomem *base, u32 etm_pid)
>> +static int etm4_probe(struct device *dev, u32 etm_pid)
>> {
>> struct etmv4_drvdata *drvdata = dev_get_drvdata(dev);
>> struct csdev_access access = { 0 };
>> @@ -2069,8 +2069,6 @@ static int etm4_probe(struct device *dev, void __iomem *base, u32 etm_pid)
>> return -ENOMEM;
>> }
>>
>> - drvdata->base = base;
>> -
>> spin_lock_init(&drvdata->spinlock);
>>
>> drvdata->cpu = coresight_get_cpu(dev);
>> @@ -2124,8 +2122,9 @@ static int etm4_probe_amba(struct amba_device *adev, const struct amba_id *id)
>> if (!drvdata)
>> return -ENOMEM;
>>
>> + drvdata->base = base;
>> dev_set_drvdata(dev, drvdata);
>> - ret = etm4_probe(dev, base, id->id);
>> + ret = etm4_probe(dev, id->id);
>> if (!ret)
>> pm_runtime_put(&adev->dev);
>>
>> @@ -2141,6 +2140,7 @@ static int etm4_probe_platform_dev(struct platform_device *pdev)
>> if (!drvdata)
>> return -ENOMEM;
>>
>> + drvdata->base = NULL;
> Very minor point, drvdata is zero alloced so it doesn't make sense to
> zero this field but not the others. It's harmless, but it might imply
> something and confuse someone.

Just to keep changes to both call sites of etm4_probe() similar i.e
etm4_probe()'s 'base' argument being pre-assigned as drvdata->base,
let's keep the NULL assignment above unchanged.

>
> Either way:
> Reviewed-by: James Clark <[email protected]>
>

2023-05-16 11:47:25

by Anshuman Khandual

[permalink] [raw]
Subject: Re: [PATCH V2 4/5] coresight: etm4x: Change etm4_platform_driver driver for MMIO devices



On 3/27/23 20:24, Suzuki K Poulose wrote:
> On 27/03/2023 06:05, Anshuman Khandual wrote:
>> Add support for handling MMIO based devices via platform driver. We need to
>> make sure that :
>>
>> 1) The APB clock, if present is enabled at probe and via runtime_pm ops
>> 2) Use the ETM4x architecture or CoreSight architecture registers to
>>     identify a device as CoreSight ETM4x, instead of relying a white list of
>>     "Peripheral IDs"
>>
>> The driver doesn't get to handle the devices yet, until we wire the ACPI
>> changes to move the devices to be handled via platform driver than the
>> etm4_amba driver.
>>
>> Cc: Mathieu Poirier <[email protected]>
>> Cc: Suzuki K Poulose <[email protected]>
>> Cc: Mike Leach <[email protected]>
>> Cc: Leo Yan <[email protected]>
>> Cc: [email protected]
>> Cc: [email protected]
>> Cc: [email protected]
>> Signed-off-by: Anshuman Khandual <[email protected]>
>> ---
>>   .../coresight/coresight-etm4x-core.c          | 62 +++++++++++++++++--
>>   drivers/hwtracing/coresight/coresight-etm4x.h |  4 ++
>>   include/linux/coresight.h                     | 47 ++++++++++++++
>>   3 files changed, 109 insertions(+), 4 deletions(-)
>>
>> diff --git a/drivers/hwtracing/coresight/coresight-etm4x-core.c b/drivers/hwtracing/coresight/coresight-etm4x-core.c
>> index 3521838ab4fb..bef205023bbe 100644
>> --- a/drivers/hwtracing/coresight/coresight-etm4x-core.c
>> +++ b/drivers/hwtracing/coresight/coresight-etm4x-core.c
>> @@ -30,6 +30,7 @@
>>   #include <linux/platform_device.h>
>>   #include <linux/pm_runtime.h>
>>   #include <linux/property.h>
>> +#include <linux/clk/clk-conf.h>
>>     #include <asm/barrier.h>
>>   #include <asm/sections.h>
>> @@ -1067,12 +1068,22 @@ static bool etm4_init_sysreg_access(struct etmv4_drvdata *drvdata,
>>       return true;
>>   }
>>   +static bool is_etm4x_devtype(void __iomem *base)
>> +{
>> +    u32 devtype = readl(base + TRCDEVTYPE);
>> +
>> +    return (devtype == ETM_DEVTYPE_ETMv4x_ARCH);
>> +}
>> +
>>   static bool etm4_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);
>>   +    if (!is_coresight_device(drvdata->base) || !is_etm4x_devtype(drvdata->base))
>> +        return false;
>> +
>>       /*
>>        * All ETMs must implement TRCDEVARCH to indicate that
>>        * the component is an ETMv4. To support any broken
>> @@ -2133,6 +2144,7 @@ static int etm4_probe_amba(struct amba_device *adev, const struct amba_id *id)
>>     static int etm4_probe_platform_dev(struct platform_device *pdev)
>>   {
>> +    struct resource *res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
>>       struct etmv4_drvdata *drvdata;
>>       int ret;
>>   @@ -2140,7 +2152,18 @@ static int etm4_probe_platform_dev(struct platform_device *pdev)
>>       if (!drvdata)
>>           return -ENOMEM;
>>   -    drvdata->base = NULL;
>> +    drvdata->pclk = coresight_get_enable_apb_pclk(&pdev->dev);
>> +    if (IS_ERR(drvdata->pclk))
>> +        return -ENODEV;
>> +
>> +    if (res) {
>> +        drvdata->base = devm_ioremap_resource(&pdev->dev, res);
>> +        if (IS_ERR(drvdata->base)) {
>> +            clk_put(drvdata->pclk);
>> +            return PTR_ERR(drvdata->base);
>> +        }
>> +    }
>> +
>>       dev_set_drvdata(&pdev->dev, drvdata);
>>       pm_runtime_get_noresume(&pdev->dev);
>>       pm_runtime_set_active(&pdev->dev);
>> @@ -2186,7 +2209,7 @@ static struct amba_cs_uci_id uci_id_etm4[] = {
>>           /*  ETMv4 UCI data */
>>           .devarch    = ETM_DEVARCH_ETMv4x_ARCH,
>>           .devarch_mask    = ETM_DEVARCH_ID_MASK,
>> -        .devtype    = 0x00000013,
>> +        .devtype    = ETM_DEVTYPE_ETMv4x_ARCH,
>>       }
>>   };
>>   @@ -2244,6 +2267,10 @@ static int __exit etm4_remove_platform_dev(struct platform_device *pdev)
>>         if (drvdata)
>>           ret = etm4_remove_dev(drvdata);
>> +
>> +    if (drvdata->pclk)
>> +        clk_put(drvdata->pclk);
>> +
>>       pm_runtime_disable(&pdev->dev);
>>       return ret;
>>   }
>> @@ -2284,7 +2311,33 @@ static struct amba_driver etm4x_amba_driver = {
>>       .id_table    = etm4_ids,
>>   };
>>   -static const struct of_device_id etm4_sysreg_match[] = {
>> +#ifdef CONFIG_PM
>> +static int etm4_runtime_suspend(struct device *dev)
>> +{
>> +    struct etmv4_drvdata *drvdata = dev_get_drvdata(dev);
>> +
>> +    if (!IS_ERR(drvdata->pclk))
>> +        clk_disable_unprepare(drvdata->pclk);
>> +
>> +    return 0;
>> +}
>> +
>> +static int etm4_runtime_resume(struct device *dev)
>> +{
>> +    struct etmv4_drvdata *drvdata = dev_get_drvdata(dev);
>> +
>> +    if (!IS_ERR(drvdata->pclk))
>> +        clk_prepare_enable(drvdata->pclk);
>> +
>> +    return 0;
>> +}
>> +#endif
>> +
>> +static const struct dev_pm_ops etm4_dev_pm_ops = {
>> +    SET_RUNTIME_PM_OPS(etm4_runtime_suspend, etm4_runtime_resume, NULL)
>> +};
>> +
>> +static const struct of_device_id etm4_match[] = {
>>       { .compatible    = "arm,coresight-etm4x-sysreg" },
>>       { .compatible    = "arm,embedded-trace-extension" },
>>       {}
>> @@ -2295,8 +2348,9 @@ static struct platform_driver etm4_platform_driver = {
>>       .remove        = etm4_remove_platform_dev,
>>       .driver            = {
>>           .name            = "coresight-etm4x",
>> -        .of_match_table        = etm4_sysreg_match,
>> +        .of_match_table        = etm4_match,
>>           .suppress_bind_attrs    = true,
>> +        .pm            = &etm4_dev_pm_ops,
>>       },
>>   };
>>   diff --git a/drivers/hwtracing/coresight/coresight-etm4x.h b/drivers/hwtracing/coresight/coresight-etm4x.h
>> index 434f4e95ee17..78dfe7949548 100644
>> --- a/drivers/hwtracing/coresight/coresight-etm4x.h
>> +++ b/drivers/hwtracing/coresight/coresight-etm4x.h
>> @@ -701,6 +701,8 @@
>>   #define ETM_DEVARCH_ETE_ARCH                        \
>>       (ETM_DEVARCH_ARCHITECT_ARM | ETM_DEVARCH_ARCHID_ETE | ETM_DEVARCH_PRESENT)
>>   +#define ETM_DEVTYPE_ETMv4x_ARCH        0x00000013
>
> This has nothing to do with ETMv4 ARCH. This indicates :
>
> [3:0] == 0x3 -> Indicates CoreSight Source
> [7:4] == 0x1 -> Generates PE trace
>
> So, we could call it : CS_DEVTYPE_PE_TRACE, but not ETMv4x

Sure, will rename it as suggested.

>
> Rest looks good to me.
>
> Suzuki
>
> _______________________________________________
> CoreSight mailing list -- [email protected]
> To unsubscribe send an email to [email protected]

2023-05-17 04:39:36

by Anshuman Khandual

[permalink] [raw]
Subject: Re: [PATCH V2 3/5] coresight: etm4x: Drop pid argument from etm4_probe()



On 3/31/23 16:36, Suzuki K Poulose wrote:
> On 27/03/2023 06:05, Anshuman Khandual wrote:
>> Coresight device pid can be retrieved from its iomem base address, which is
>> stored in 'struct etm4x_drvdata'. This drops pid argument from etm4_probe()
>> and 'struct etm4_init_arg'. Instead etm4_check_arch_features() derives the
>> coresight device pid with a new helper coresight_get_pid(), right before it
>> is consumed in etm4_hisi_match_pid().
>>
>> Cc: Mathieu Poirier <[email protected]>
>> Cc: Suzuki K Poulose <[email protected]>
>> Cc: Mike Leach <[email protected]>
>> Cc: Leo Yan <[email protected]>
>> Cc: [email protected]
>> Cc: [email protected]
>> Cc: [email protected]
>> Signed-off-by: Anshuman Khandual <[email protected]>
>> ---
>>   .../coresight/coresight-etm4x-core.c          | 21 +++++++------------
>>   include/linux/coresight.h                     | 12 +++++++++++
>>   2 files changed, 20 insertions(+), 13 deletions(-)
>>
>> diff --git a/drivers/hwtracing/coresight/coresight-etm4x-core.c b/drivers/hwtracing/coresight/coresight-etm4x-core.c
>> index 5d77571a8df9..3521838ab4fb 100644
>> --- a/drivers/hwtracing/coresight/coresight-etm4x-core.c
>> +++ b/drivers/hwtracing/coresight/coresight-etm4x-core.c
>> @@ -66,7 +66,6 @@ static u64 etm4_get_access_type(struct etmv4_config *config);
>>   static enum cpuhp_state hp_online;
>>     struct etm4_init_arg {
>> -    unsigned int        pid;
>>       struct device        *dev;
>>       struct csdev_access    *csa;
>>   };
>> @@ -370,8 +369,10 @@ static void etm4_disable_arch_specific(struct etmv4_drvdata *drvdata)
>>   }
>>     static void etm4_check_arch_features(struct etmv4_drvdata *drvdata,
>> -                      unsigned int id)
>> +                     struct csdev_access *csa)
>>   {
>> +    unsigned int id = coresight_get_pid(csa);
>> +
>
> This throws up the following error on an ETE.
>
> ete: trying to read unsupported register @fe0
>
> So, I guess this must be performed only for iomem based
> devices. System instruction based device must be identified
> by MIDR_EL1/REVIDR_EL1 if needed for specific erratum.
> This is not required now. So, we could bail out early
> if we are system instruction based device.

Will bail out on non iomem devices via drvdata->base address switch.

--- a/drivers/hwtracing/coresight/coresight-etm4x-core.c
+++ b/drivers/hwtracing/coresight/coresight-etm4x-core.c
@@ -373,9 +373,10 @@ static void etm4_disable_arch_specific(struct etmv4_drvdata *drvdata)
static void etm4_check_arch_features(struct etmv4_drvdata *drvdata,
struct csdev_access *csa)
{
- unsigned int id = coresight_get_pid(csa);
+ if (!drvdata->base)
+ return;

- if (etm4_hisi_match_pid(id))
+ if (etm4_hisi_match_pid(coresight_get_pid(csa)))
set_bit(ETM4_IMPDEF_HISI_CORE_COMMIT, drvdata->arch_features);
}
#else

>
>
>>       if (etm4_hisi_match_pid(id))
>>           set_bit(ETM4_IMPDEF_HISI_CORE_COMMIT, drvdata->arch_features);
>>   }
>> @@ -385,7 +386,7 @@ static void etm4_disable_arch_specific(struct etmv4_drvdata *drvdata)
>>   }
>>     static void etm4_check_arch_features(struct etmv4_drvdata *drvdata,
>> -                     unsigned int id)
>> +                     struct csdev_access *csa)
>>   {
>>   }
>>   #endif /* CONFIG_ETM4X_IMPDEF_FEATURE */
>> @@ -1165,7 +1166,7 @@ static void etm4_init_arch_data(void *info)
>>       etm4_os_unlock_csa(drvdata, csa);
>>       etm4_cs_unlock(drvdata, csa);
>>   -    etm4_check_arch_features(drvdata, init_arg->pid);
>> +    etm4_check_arch_features(drvdata, csa);
>>         /* find all capabilities of the tracing unit */
>>       etmidr0 = etm4x_relaxed_read32(csa, TRCIDR0);
>> @@ -2048,7 +2049,7 @@ static int etm4_add_coresight_dev(struct etm4_init_arg *init_arg)
>>       return 0;
>>   }
>>   -static int etm4_probe(struct device *dev, u32 etm_pid)
>> +static int etm4_probe(struct device *dev)
>>   {
>>       struct etmv4_drvdata *drvdata = dev_get_drvdata(dev);
>>       struct csdev_access access = { 0 };
>> @@ -2077,7 +2078,6 @@ static int etm4_probe(struct device *dev, u32 etm_pid)
>>         init_arg.dev = dev;
>>       init_arg.csa = &access;
>> -    init_arg.pid = etm_pid;
>>         /*
>>        * Serialize against CPUHP callbacks to avoid race condition
>> @@ -2124,7 +2124,7 @@ static int etm4_probe_amba(struct amba_device *adev, const struct amba_id *id)
>>         drvdata->base = base;
>>       dev_set_drvdata(dev, drvdata);
>> -    ret = etm4_probe(dev, id->id);
>> +    ret = etm4_probe(dev);
>>       if (!ret)
>>           pm_runtime_put(&adev->dev);
>>   @@ -2146,12 +2146,7 @@ static int etm4_probe_platform_dev(struct platform_device *pdev)
>>       pm_runtime_set_active(&pdev->dev);
>>       pm_runtime_enable(&pdev->dev);
>>   -    /*
>> -     * System register based devices could match the
>> -     * HW by reading appropriate registers on the HW
>> -     * and thus we could skip the PID.
>> -     */
>> -    ret = etm4_probe(&pdev->dev, 0);
>> +    ret = etm4_probe(&pdev->dev);
>>         pm_runtime_put(&pdev->dev);
>>       return ret;
>> diff --git a/include/linux/coresight.h b/include/linux/coresight.h
>> index f19a47b9bb5a..f85b041ea475 100644
>> --- a/include/linux/coresight.h
>> +++ b/include/linux/coresight.h
>> @@ -370,6 +370,18 @@ static inline u32 csdev_access_relaxed_read32(struct csdev_access *csa,
>>       return csa->read(offset, true, false);
>>   }
>>   +#define CORESIGHT_PIDRn(i)    (0xFE0 + ((i) * 4))
>> +
>> +static inline u32 coresight_get_pid(struct csdev_access *csa)
>> +{
>> +    u32 i, pid = 0;
>> +
>> +    for (i = 0; i < 4; i++)
>> +        pid |= csdev_access_relaxed_read32(csa, CORESIGHT_PIDRn(i)) << (i * 8);
>
> Given the above, we could make this iomem specific.

We could change coresight_get_pid() to take iomem base address instead
and fetch the pid. But is not the existing csdev_access based approach
better and more generic ?

#define CORESIGHT_PIDRn(i) (0xFE0 + ((i) * 4))

static inline u32 coresight_get_pid(void __iomem *base)
{
u32 i, pid = 0;

for (i = 0; i < 4; i++)
pid |= readl(base + CORESIGHT_PIDRn(i)) << (i * 8);

return pid;
}

2023-05-17 09:43:46

by Suzuki K Poulose

[permalink] [raw]
Subject: Re: [PATCH V2 3/5] coresight: etm4x: Drop pid argument from etm4_probe()

On 17/05/2023 05:32, Anshuman Khandual wrote:
>
>
> On 3/31/23 16:36, Suzuki K Poulose wrote:
>> On 27/03/2023 06:05, Anshuman Khandual wrote:
>>> Coresight device pid can be retrieved from its iomem base address, which is
>>> stored in 'struct etm4x_drvdata'. This drops pid argument from etm4_probe()
>>> and 'struct etm4_init_arg'. Instead etm4_check_arch_features() derives the
>>> coresight device pid with a new helper coresight_get_pid(), right before it
>>> is consumed in etm4_hisi_match_pid().
>>>
>>> Cc: Mathieu Poirier <[email protected]>
>>> Cc: Suzuki K Poulose <[email protected]>
>>> Cc: Mike Leach <[email protected]>
>>> Cc: Leo Yan <[email protected]>
>>> Cc: [email protected]
>>> Cc: [email protected]
>>> Cc: [email protected]
>>> Signed-off-by: Anshuman Khandual <[email protected]>
>>> ---
>>>   .../coresight/coresight-etm4x-core.c          | 21 +++++++------------
>>>   include/linux/coresight.h                     | 12 +++++++++++
>>>   2 files changed, 20 insertions(+), 13 deletions(-)
>>>
>>> diff --git a/drivers/hwtracing/coresight/coresight-etm4x-core.c b/drivers/hwtracing/coresight/coresight-etm4x-core.c
>>> index 5d77571a8df9..3521838ab4fb 100644
>>> --- a/drivers/hwtracing/coresight/coresight-etm4x-core.c
>>> +++ b/drivers/hwtracing/coresight/coresight-etm4x-core.c
>>> @@ -66,7 +66,6 @@ static u64 etm4_get_access_type(struct etmv4_config *config);
>>>   static enum cpuhp_state hp_online;
>>>     struct etm4_init_arg {
>>> -    unsigned int        pid;
>>>       struct device        *dev;
>>>       struct csdev_access    *csa;
>>>   };
>>> @@ -370,8 +369,10 @@ static void etm4_disable_arch_specific(struct etmv4_drvdata *drvdata)
>>>   }
>>>     static void etm4_check_arch_features(struct etmv4_drvdata *drvdata,
>>> -                      unsigned int id)
>>> +                     struct csdev_access *csa)
>>>   {
>>> +    unsigned int id = coresight_get_pid(csa);
>>> +
>>
>> This throws up the following error on an ETE.
>>
>> ete: trying to read unsupported register @fe0
>>
>> So, I guess this must be performed only for iomem based
>> devices. System instruction based device must be identified
>> by MIDR_EL1/REVIDR_EL1 if needed for specific erratum.
>> This is not required now. So, we could bail out early
>> if we are system instruction based device.
>
> Will bail out on non iomem devices via drvdata->base address switch.
>
> --- a/drivers/hwtracing/coresight/coresight-etm4x-core.c
> +++ b/drivers/hwtracing/coresight/coresight-etm4x-core.c
> @@ -373,9 +373,10 @@ static void etm4_disable_arch_specific(struct etmv4_drvdata *drvdata)
> static void etm4_check_arch_features(struct etmv4_drvdata *drvdata,
> struct csdev_access *csa)
> {
> - unsigned int id = coresight_get_pid(csa);
> + if (!drvdata->base)
> + return;

I would use !csa->io_mem to be more readerf friendly.

>
> - if (etm4_hisi_match_pid(id))
> + if (etm4_hisi_match_pid(coresight_get_pid(csa)))
> set_bit(ETM4_IMPDEF_HISI_CORE_COMMIT, drvdata->arch_features);
> }
> #else
>
>>
>>
>>>       if (etm4_hisi_match_pid(id))
>>>           set_bit(ETM4_IMPDEF_HISI_CORE_COMMIT, drvdata->arch_features);
>>>   }
>>> @@ -385,7 +386,7 @@ static void etm4_disable_arch_specific(struct etmv4_drvdata *drvdata)
>>>   }
>>>     static void etm4_check_arch_features(struct etmv4_drvdata *drvdata,
>>> -                     unsigned int id)
>>> +                     struct csdev_access *csa)
>>>   {
>>>   }
>>>   #endif /* CONFIG_ETM4X_IMPDEF_FEATURE */
>>> @@ -1165,7 +1166,7 @@ static void etm4_init_arch_data(void *info)
>>>       etm4_os_unlock_csa(drvdata, csa);
>>>       etm4_cs_unlock(drvdata, csa);
>>>   -    etm4_check_arch_features(drvdata, init_arg->pid);
>>> +    etm4_check_arch_features(drvdata, csa);
>>>         /* find all capabilities of the tracing unit */
>>>       etmidr0 = etm4x_relaxed_read32(csa, TRCIDR0);
>>> @@ -2048,7 +2049,7 @@ static int etm4_add_coresight_dev(struct etm4_init_arg *init_arg)
>>>       return 0;
>>>   }
>>>   -static int etm4_probe(struct device *dev, u32 etm_pid)
>>> +static int etm4_probe(struct device *dev)
>>>   {
>>>       struct etmv4_drvdata *drvdata = dev_get_drvdata(dev);
>>>       struct csdev_access access = { 0 };
>>> @@ -2077,7 +2078,6 @@ static int etm4_probe(struct device *dev, u32 etm_pid)
>>>         init_arg.dev = dev;
>>>       init_arg.csa = &access;
>>> -    init_arg.pid = etm_pid;
>>>         /*
>>>        * Serialize against CPUHP callbacks to avoid race condition
>>> @@ -2124,7 +2124,7 @@ static int etm4_probe_amba(struct amba_device *adev, const struct amba_id *id)
>>>         drvdata->base = base;
>>>       dev_set_drvdata(dev, drvdata);
>>> -    ret = etm4_probe(dev, id->id);
>>> +    ret = etm4_probe(dev);
>>>       if (!ret)
>>>           pm_runtime_put(&adev->dev);
>>>   @@ -2146,12 +2146,7 @@ static int etm4_probe_platform_dev(struct platform_device *pdev)
>>>       pm_runtime_set_active(&pdev->dev);
>>>       pm_runtime_enable(&pdev->dev);
>>>   -    /*
>>> -     * System register based devices could match the
>>> -     * HW by reading appropriate registers on the HW
>>> -     * and thus we could skip the PID.
>>> -     */
>>> -    ret = etm4_probe(&pdev->dev, 0);
>>> +    ret = etm4_probe(&pdev->dev);
>>>         pm_runtime_put(&pdev->dev);
>>>       return ret;
>>> diff --git a/include/linux/coresight.h b/include/linux/coresight.h
>>> index f19a47b9bb5a..f85b041ea475 100644
>>> --- a/include/linux/coresight.h
>>> +++ b/include/linux/coresight.h
>>> @@ -370,6 +370,18 @@ static inline u32 csdev_access_relaxed_read32(struct csdev_access *csa,
>>>       return csa->read(offset, true, false);
>>>   }
>>>   +#define CORESIGHT_PIDRn(i)    (0xFE0 + ((i) * 4))
>>> +
>>> +static inline u32 coresight_get_pid(struct csdev_access *csa)
>>> +{
>>> +    u32 i, pid = 0;
>>> +
>>> +    for (i = 0; i < 4; i++)
>>> +        pid |= csdev_access_relaxed_read32(csa, CORESIGHT_PIDRn(i)) << (i * 8);
>>
>> Given the above, we could make this iomem specific.
>
> We could change coresight_get_pid() to take iomem base address instead
> and fetch the pid. But is not the existing csdev_access based approach
> better and more generic ?

Yes, true, lets leave it with csdev_access, as it is coresight specific
and not ETMv4.

Cheers
Suzuki