drm/v3d: Add a little debugfs entry for measuring the core clock.
authorEric Anholt <eric@anholt.net>
Fri, 28 Sep 2018 23:21:24 +0000 (16:21 -0700)
committerEric Anholt <eric@anholt.net>
Mon, 15 Oct 2018 20:10:47 +0000 (13:10 -0700)
This adds just enough performance counter support to measure the
clock.  We don't have linux kernel drivers for the clock driving the
HW, and this was useful for determining that the V3D HW is running on
a slow clock, not that the driver was slow.

Signed-off-by: Eric Anholt <eric@anholt.net>
Link: https://patchwork.freedesktop.org/patch/msgid/20180928232126.4332-2-eric@anholt.net
Reviewed-by: Boris Brezillon <boris.brezillon@bootlin.com>
drivers/gpu/drm/v3d/v3d_debugfs.c
drivers/gpu/drm/v3d/v3d_regs.h

index 4db62c54574828315f56215bf59ca5986cb7995e..d48008adb085f3d5c4458ad45e086eb12f670577 100644 (file)
@@ -176,9 +176,44 @@ static int v3d_debugfs_bo_stats(struct seq_file *m, void *unused)
        return 0;
 }
 
+static int v3d_measure_clock(struct seq_file *m, void *unused)
+{
+       struct drm_info_node *node = (struct drm_info_node *)m->private;
+       struct drm_device *dev = node->minor->dev;
+       struct v3d_dev *v3d = to_v3d_dev(dev);
+       uint32_t cycles;
+       int core = 0;
+       int measure_ms = 1000;
+
+       if (v3d->ver >= 40) {
+               V3D_CORE_WRITE(core, V3D_V4_PCTR_0_SRC_0_3,
+                              V3D_SET_FIELD(V3D_PCTR_CYCLE_COUNT,
+                                            V3D_PCTR_S0));
+               V3D_CORE_WRITE(core, V3D_V4_PCTR_0_CLR, 1);
+               V3D_CORE_WRITE(core, V3D_V4_PCTR_0_EN, 1);
+       } else {
+               V3D_CORE_WRITE(core, V3D_V3_PCTR_0_PCTRS0,
+                              V3D_PCTR_CYCLE_COUNT);
+               V3D_CORE_WRITE(core, V3D_V3_PCTR_0_CLR, 1);
+               V3D_CORE_WRITE(core, V3D_V3_PCTR_0_EN,
+                              V3D_V3_PCTR_0_EN_ENABLE |
+                              1);
+       }
+       msleep(measure_ms);
+       cycles = V3D_CORE_READ(core, V3D_PCTR_0_PCTR0);
+
+       seq_printf(m, "cycles: %d (%d.%d Mhz)\n",
+                  cycles,
+                  cycles / (measure_ms * 1000),
+                  (cycles / (measure_ms * 100)) % 10);
+
+       return 0;
+}
+
 static const struct drm_info_list v3d_debugfs_list[] = {
        {"v3d_ident", v3d_v3d_debugfs_ident, 0},
        {"v3d_regs", v3d_v3d_debugfs_regs, 0},
+       {"measure_clock", v3d_measure_clock, 0},
        {"bo_stats", v3d_debugfs_bo_stats, 0},
 };
 
index 854046565989e12c5b2e822f82b8fae40c01e5b0..c3a5e4e44f731d586c5e3b17a80aa6b27a7fd9a9 100644 (file)
 # define V3D_PTB_BXCF_RWORDERDISA                      BIT(1)
 # define V3D_PTB_BXCF_CLIPDISA                         BIT(0)
 
+#define V3D_V3_PCTR_0_EN                               0x00674
+#define V3D_V3_PCTR_0_EN_ENABLE                        BIT(31)
+#define V3D_V4_PCTR_0_EN                               0x00650
+/* When a bit is set, resets the counter to 0. */
+#define V3D_V3_PCTR_0_CLR                              0x00670
+#define V3D_V4_PCTR_0_CLR                              0x00654
+#define V3D_PCTR_0_OVERFLOW                            0x00658
+
+#define V3D_V3_PCTR_0_PCTRS0                           0x00684
+#define V3D_V3_PCTR_0_PCTRS15                          0x00660
+#define V3D_V3_PCTR_0_PCTRSX(x)                        (V3D_V3_PCTR_0_PCTRS0 + \
+                                                       4 * (x))
+/* Each src reg muxes four counters each. */
+#define V3D_V4_PCTR_0_SRC_0_3                          0x00660
+#define V3D_V4_PCTR_0_SRC_28_31                        0x0067c
+# define V3D_PCTR_S0_MASK                              V3D_MASK(6, 0)
+# define V3D_PCTR_S0_SHIFT                             0
+# define V3D_PCTR_S1_MASK                              V3D_MASK(14, 8)
+# define V3D_PCTR_S1_SHIFT                             8
+# define V3D_PCTR_S2_MASK                              V3D_MASK(22, 16)
+# define V3D_PCTR_S2_SHIFT                             16
+# define V3D_PCTR_S3_MASK                              V3D_MASK(30, 24)
+# define V3D_PCTR_S3_SHIFT                             24
+# define V3D_PCTR_CYCLE_COUNT                          32
+
+/* Output values of the counters. */
+#define V3D_PCTR_0_PCTR0                               0x00680
+#define V3D_PCTR_0_PCTR31                              0x006fc
+#define V3D_PCTR_0_PCTRX(x)                            (V3D_PCTR_0_PCTR0 + \
+                                                       4 * (x))
 #define V3D_GMP_STATUS                                 0x00800
 # define V3D_GMP_STATUS_GMPRST                         BIT(31)
 # define V3D_GMP_STATUS_WR_COUNT_MASK                  V3D_MASK(30, 24)