root/drivers/gpu/drm/v3d/v3d_debugfs.c

/* [<][>][^][v][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. v3d_v3d_debugfs_regs
  2. v3d_v3d_debugfs_ident
  3. v3d_debugfs_bo_stats
  4. v3d_measure_clock
  5. v3d_debugfs_init

   1 // SPDX-License-Identifier: GPL-2.0+
   2 /* Copyright (C) 2014-2018 Broadcom */
   3 
   4 #include <linux/circ_buf.h>
   5 #include <linux/ctype.h>
   6 #include <linux/debugfs.h>
   7 #include <linux/pm_runtime.h>
   8 #include <linux/seq_file.h>
   9 
  10 #include <drm/drm_debugfs.h>
  11 
  12 #include "v3d_drv.h"
  13 #include "v3d_regs.h"
  14 
  15 #define REGDEF(reg) { reg, #reg }
  16 struct v3d_reg_def {
  17         u32 reg;
  18         const char *name;
  19 };
  20 
  21 static const struct v3d_reg_def v3d_hub_reg_defs[] = {
  22         REGDEF(V3D_HUB_AXICFG),
  23         REGDEF(V3D_HUB_UIFCFG),
  24         REGDEF(V3D_HUB_IDENT0),
  25         REGDEF(V3D_HUB_IDENT1),
  26         REGDEF(V3D_HUB_IDENT2),
  27         REGDEF(V3D_HUB_IDENT3),
  28         REGDEF(V3D_HUB_INT_STS),
  29         REGDEF(V3D_HUB_INT_MSK_STS),
  30 
  31         REGDEF(V3D_MMU_CTL),
  32         REGDEF(V3D_MMU_VIO_ADDR),
  33         REGDEF(V3D_MMU_VIO_ID),
  34         REGDEF(V3D_MMU_DEBUG_INFO),
  35 };
  36 
  37 static const struct v3d_reg_def v3d_gca_reg_defs[] = {
  38         REGDEF(V3D_GCA_SAFE_SHUTDOWN),
  39         REGDEF(V3D_GCA_SAFE_SHUTDOWN_ACK),
  40 };
  41 
  42 static const struct v3d_reg_def v3d_core_reg_defs[] = {
  43         REGDEF(V3D_CTL_IDENT0),
  44         REGDEF(V3D_CTL_IDENT1),
  45         REGDEF(V3D_CTL_IDENT2),
  46         REGDEF(V3D_CTL_MISCCFG),
  47         REGDEF(V3D_CTL_INT_STS),
  48         REGDEF(V3D_CTL_INT_MSK_STS),
  49         REGDEF(V3D_CLE_CT0CS),
  50         REGDEF(V3D_CLE_CT0CA),
  51         REGDEF(V3D_CLE_CT0EA),
  52         REGDEF(V3D_CLE_CT1CS),
  53         REGDEF(V3D_CLE_CT1CA),
  54         REGDEF(V3D_CLE_CT1EA),
  55 
  56         REGDEF(V3D_PTB_BPCA),
  57         REGDEF(V3D_PTB_BPCS),
  58 
  59         REGDEF(V3D_GMP_STATUS),
  60         REGDEF(V3D_GMP_CFG),
  61         REGDEF(V3D_GMP_VIO_ADDR),
  62 
  63         REGDEF(V3D_ERR_FDBGO),
  64         REGDEF(V3D_ERR_FDBGB),
  65         REGDEF(V3D_ERR_FDBGS),
  66         REGDEF(V3D_ERR_STAT),
  67 };
  68 
  69 static const struct v3d_reg_def v3d_csd_reg_defs[] = {
  70         REGDEF(V3D_CSD_STATUS),
  71         REGDEF(V3D_CSD_CURRENT_CFG0),
  72         REGDEF(V3D_CSD_CURRENT_CFG1),
  73         REGDEF(V3D_CSD_CURRENT_CFG2),
  74         REGDEF(V3D_CSD_CURRENT_CFG3),
  75         REGDEF(V3D_CSD_CURRENT_CFG4),
  76         REGDEF(V3D_CSD_CURRENT_CFG5),
  77         REGDEF(V3D_CSD_CURRENT_CFG6),
  78 };
  79 
  80 static int v3d_v3d_debugfs_regs(struct seq_file *m, void *unused)
  81 {
  82         struct drm_info_node *node = (struct drm_info_node *)m->private;
  83         struct drm_device *dev = node->minor->dev;
  84         struct v3d_dev *v3d = to_v3d_dev(dev);
  85         int i, core;
  86 
  87         for (i = 0; i < ARRAY_SIZE(v3d_hub_reg_defs); i++) {
  88                 seq_printf(m, "%s (0x%04x): 0x%08x\n",
  89                            v3d_hub_reg_defs[i].name, v3d_hub_reg_defs[i].reg,
  90                            V3D_READ(v3d_hub_reg_defs[i].reg));
  91         }
  92 
  93         if (v3d->ver < 41) {
  94                 for (i = 0; i < ARRAY_SIZE(v3d_gca_reg_defs); i++) {
  95                         seq_printf(m, "%s (0x%04x): 0x%08x\n",
  96                                    v3d_gca_reg_defs[i].name,
  97                                    v3d_gca_reg_defs[i].reg,
  98                                    V3D_GCA_READ(v3d_gca_reg_defs[i].reg));
  99                 }
 100         }
 101 
 102         for (core = 0; core < v3d->cores; core++) {
 103                 for (i = 0; i < ARRAY_SIZE(v3d_core_reg_defs); i++) {
 104                         seq_printf(m, "core %d %s (0x%04x): 0x%08x\n",
 105                                    core,
 106                                    v3d_core_reg_defs[i].name,
 107                                    v3d_core_reg_defs[i].reg,
 108                                    V3D_CORE_READ(core,
 109                                                  v3d_core_reg_defs[i].reg));
 110                 }
 111 
 112                 if (v3d_has_csd(v3d)) {
 113                         for (i = 0; i < ARRAY_SIZE(v3d_csd_reg_defs); i++) {
 114                                 seq_printf(m, "core %d %s (0x%04x): 0x%08x\n",
 115                                            core,
 116                                            v3d_csd_reg_defs[i].name,
 117                                            v3d_csd_reg_defs[i].reg,
 118                                            V3D_CORE_READ(core,
 119                                                          v3d_csd_reg_defs[i].reg));
 120                         }
 121                 }
 122         }
 123 
 124         return 0;
 125 }
 126 
 127 static int v3d_v3d_debugfs_ident(struct seq_file *m, void *unused)
 128 {
 129         struct drm_info_node *node = (struct drm_info_node *)m->private;
 130         struct drm_device *dev = node->minor->dev;
 131         struct v3d_dev *v3d = to_v3d_dev(dev);
 132         u32 ident0, ident1, ident2, ident3, cores;
 133         int ret, core;
 134 
 135         ret = pm_runtime_get_sync(v3d->dev);
 136         if (ret < 0)
 137                 return ret;
 138 
 139         ident0 = V3D_READ(V3D_HUB_IDENT0);
 140         ident1 = V3D_READ(V3D_HUB_IDENT1);
 141         ident2 = V3D_READ(V3D_HUB_IDENT2);
 142         ident3 = V3D_READ(V3D_HUB_IDENT3);
 143         cores = V3D_GET_FIELD(ident1, V3D_HUB_IDENT1_NCORES);
 144 
 145         seq_printf(m, "Revision:   %d.%d.%d.%d\n",
 146                    V3D_GET_FIELD(ident1, V3D_HUB_IDENT1_TVER),
 147                    V3D_GET_FIELD(ident1, V3D_HUB_IDENT1_REV),
 148                    V3D_GET_FIELD(ident3, V3D_HUB_IDENT3_IPREV),
 149                    V3D_GET_FIELD(ident3, V3D_HUB_IDENT3_IPIDX));
 150         seq_printf(m, "MMU:        %s\n",
 151                    (ident2 & V3D_HUB_IDENT2_WITH_MMU) ? "yes" : "no");
 152         seq_printf(m, "TFU:        %s\n",
 153                    (ident1 & V3D_HUB_IDENT1_WITH_TFU) ? "yes" : "no");
 154         seq_printf(m, "TSY:        %s\n",
 155                    (ident1 & V3D_HUB_IDENT1_WITH_TSY) ? "yes" : "no");
 156         seq_printf(m, "MSO:        %s\n",
 157                    (ident1 & V3D_HUB_IDENT1_WITH_MSO) ? "yes" : "no");
 158         seq_printf(m, "L3C:        %s (%dkb)\n",
 159                    (ident1 & V3D_HUB_IDENT1_WITH_L3C) ? "yes" : "no",
 160                    V3D_GET_FIELD(ident2, V3D_HUB_IDENT2_L3C_NKB));
 161 
 162         for (core = 0; core < cores; core++) {
 163                 u32 misccfg;
 164                 u32 nslc, ntmu, qups;
 165 
 166                 ident0 = V3D_CORE_READ(core, V3D_CTL_IDENT0);
 167                 ident1 = V3D_CORE_READ(core, V3D_CTL_IDENT1);
 168                 ident2 = V3D_CORE_READ(core, V3D_CTL_IDENT2);
 169                 misccfg = V3D_CORE_READ(core, V3D_CTL_MISCCFG);
 170 
 171                 nslc = V3D_GET_FIELD(ident1, V3D_IDENT1_NSLC);
 172                 ntmu = V3D_GET_FIELD(ident1, V3D_IDENT1_NTMU);
 173                 qups = V3D_GET_FIELD(ident1, V3D_IDENT1_QUPS);
 174 
 175                 seq_printf(m, "Core %d:\n", core);
 176                 seq_printf(m, "  Revision:     %d.%d\n",
 177                            V3D_GET_FIELD(ident0, V3D_IDENT0_VER),
 178                            V3D_GET_FIELD(ident1, V3D_IDENT1_REV));
 179                 seq_printf(m, "  Slices:       %d\n", nslc);
 180                 seq_printf(m, "  TMUs:         %d\n", nslc * ntmu);
 181                 seq_printf(m, "  QPUs:         %d\n", nslc * qups);
 182                 seq_printf(m, "  Semaphores:   %d\n",
 183                            V3D_GET_FIELD(ident1, V3D_IDENT1_NSEM));
 184                 seq_printf(m, "  BCG int:      %d\n",
 185                            (ident2 & V3D_IDENT2_BCG_INT) != 0);
 186                 seq_printf(m, "  Override TMU: %d\n",
 187                            (misccfg & V3D_MISCCFG_OVRTMUOUT) != 0);
 188         }
 189 
 190         pm_runtime_mark_last_busy(v3d->dev);
 191         pm_runtime_put_autosuspend(v3d->dev);
 192 
 193         return 0;
 194 }
 195 
 196 static int v3d_debugfs_bo_stats(struct seq_file *m, void *unused)
 197 {
 198         struct drm_info_node *node = (struct drm_info_node *)m->private;
 199         struct drm_device *dev = node->minor->dev;
 200         struct v3d_dev *v3d = to_v3d_dev(dev);
 201 
 202         mutex_lock(&v3d->bo_lock);
 203         seq_printf(m, "allocated bos:          %d\n",
 204                    v3d->bo_stats.num_allocated);
 205         seq_printf(m, "allocated bo size (kb): %ld\n",
 206                    (long)v3d->bo_stats.pages_allocated << (PAGE_SHIFT - 10));
 207         mutex_unlock(&v3d->bo_lock);
 208 
 209         return 0;
 210 }
 211 
 212 static int v3d_measure_clock(struct seq_file *m, void *unused)
 213 {
 214         struct drm_info_node *node = (struct drm_info_node *)m->private;
 215         struct drm_device *dev = node->minor->dev;
 216         struct v3d_dev *v3d = to_v3d_dev(dev);
 217         uint32_t cycles;
 218         int core = 0;
 219         int measure_ms = 1000;
 220         int ret;
 221 
 222         ret = pm_runtime_get_sync(v3d->dev);
 223         if (ret < 0)
 224                 return ret;
 225 
 226         if (v3d->ver >= 40) {
 227                 V3D_CORE_WRITE(core, V3D_V4_PCTR_0_SRC_0_3,
 228                                V3D_SET_FIELD(V3D_PCTR_CYCLE_COUNT,
 229                                              V3D_PCTR_S0));
 230                 V3D_CORE_WRITE(core, V3D_V4_PCTR_0_CLR, 1);
 231                 V3D_CORE_WRITE(core, V3D_V4_PCTR_0_EN, 1);
 232         } else {
 233                 V3D_CORE_WRITE(core, V3D_V3_PCTR_0_PCTRS0,
 234                                V3D_PCTR_CYCLE_COUNT);
 235                 V3D_CORE_WRITE(core, V3D_V3_PCTR_0_CLR, 1);
 236                 V3D_CORE_WRITE(core, V3D_V3_PCTR_0_EN,
 237                                V3D_V3_PCTR_0_EN_ENABLE |
 238                                1);
 239         }
 240         msleep(measure_ms);
 241         cycles = V3D_CORE_READ(core, V3D_PCTR_0_PCTR0);
 242 
 243         seq_printf(m, "cycles: %d (%d.%d Mhz)\n",
 244                    cycles,
 245                    cycles / (measure_ms * 1000),
 246                    (cycles / (measure_ms * 100)) % 10);
 247 
 248         pm_runtime_mark_last_busy(v3d->dev);
 249         pm_runtime_put_autosuspend(v3d->dev);
 250 
 251         return 0;
 252 }
 253 
 254 static const struct drm_info_list v3d_debugfs_list[] = {
 255         {"v3d_ident", v3d_v3d_debugfs_ident, 0},
 256         {"v3d_regs", v3d_v3d_debugfs_regs, 0},
 257         {"measure_clock", v3d_measure_clock, 0},
 258         {"bo_stats", v3d_debugfs_bo_stats, 0},
 259 };
 260 
 261 int
 262 v3d_debugfs_init(struct drm_minor *minor)
 263 {
 264         return drm_debugfs_create_files(v3d_debugfs_list,
 265                                         ARRAY_SIZE(v3d_debugfs_list),
 266                                         minor->debugfs_root, minor);
 267 }

/* [<][>][^][v][top][bottom][index][help] */