Currently, even though V3D 7.1 has 93 performance counters, it is not
possible to create counters bigger than 87, as
`v3d_perfmon_create_ioctl()` understands that counters bigger than 87
are invalid.

Therefore, create a device variable to expose the maximum
number of counters for a given V3D version and make
`v3d_perfmon_create_ioctl()` check this variable.

This commit fixes CTS failures in the performance queries tests
(dEQP-VK.query_pool.performance_query.*) [1]

Link: 
https://gitlab.freedesktop.org/mesa/mesa/-/commit/ea1f09a5f21839f4f3b93610b58507c4bd9b9b81
 [1]
Fixes: 6fd9487147c4 ("drm/v3d: add brcm,2712-v3d as a compatible V3D device")
Signed-off-by: Maíra Canal <mca...@igalia.com>
---
 drivers/gpu/drm/v3d/v3d_drv.c     | 7 +++++++
 drivers/gpu/drm/v3d/v3d_drv.h     | 5 +++++
 drivers/gpu/drm/v3d/v3d_perfmon.c | 3 ++-
 3 files changed, 14 insertions(+), 1 deletion(-)

diff --git a/drivers/gpu/drm/v3d/v3d_drv.c b/drivers/gpu/drm/v3d/v3d_drv.c
index 28b7ddce7747..6b9dd26df9fe 100644
--- a/drivers/gpu/drm/v3d/v3d_drv.c
+++ b/drivers/gpu/drm/v3d/v3d_drv.c
@@ -294,6 +294,13 @@ static int v3d_platform_drm_probe(struct platform_device 
*pdev)
        v3d->cores = V3D_GET_FIELD(ident1, V3D_HUB_IDENT1_NCORES);
        WARN_ON(v3d->cores > 1); /* multicore not yet implemented */
 
+       if (v3d->ver >= 71)
+               v3d->max_counters = ARRAY_SIZE(v3d_v71_performance_counters);
+       else if (v3d->ver >= 42)
+               v3d->max_counters = ARRAY_SIZE(v3d_v42_performance_counters);
+       else
+               v3d->max_counters = 0;
+
        v3d->reset = devm_reset_control_get_exclusive(dev, NULL);
        if (IS_ERR(v3d->reset)) {
                ret = PTR_ERR(v3d->reset);
diff --git a/drivers/gpu/drm/v3d/v3d_drv.h b/drivers/gpu/drm/v3d/v3d_drv.h
index 671375a3bb66..bd1e38f7d10a 100644
--- a/drivers/gpu/drm/v3d/v3d_drv.h
+++ b/drivers/gpu/drm/v3d/v3d_drv.h
@@ -104,6 +104,11 @@ struct v3d_dev {
        int ver;
        bool single_irq_line;
 
+       /* Different revisions of V3D have different total number of performance
+        * counters
+        */
+       unsigned int max_counters;
+
        void __iomem *hub_regs;
        void __iomem *core_regs[3];
        void __iomem *bridge_regs;
diff --git a/drivers/gpu/drm/v3d/v3d_perfmon.c 
b/drivers/gpu/drm/v3d/v3d_perfmon.c
index e1be7368b87d..f268d9466c0f 100644
--- a/drivers/gpu/drm/v3d/v3d_perfmon.c
+++ b/drivers/gpu/drm/v3d/v3d_perfmon.c
@@ -123,6 +123,7 @@ int v3d_perfmon_create_ioctl(struct drm_device *dev, void 
*data,
 {
        struct v3d_file_priv *v3d_priv = file_priv->driver_priv;
        struct drm_v3d_perfmon_create *req = data;
+       struct v3d_dev *v3d = v3d_priv->v3d;
        struct v3d_perfmon *perfmon;
        unsigned int i;
        int ret;
@@ -134,7 +135,7 @@ int v3d_perfmon_create_ioctl(struct drm_device *dev, void 
*data,
 
        /* Make sure all counters are valid. */
        for (i = 0; i < req->ncounters; i++) {
-               if (req->counters[i] >= V3D_PERFCNT_NUM)
+               if (req->counters[i] >= v3d->max_counters)
                        return -EINVAL;
        }
 
-- 
2.44.0

Reply via email to