root/drivers/gpu/drm/msm/adreno/a5xx_debugfs.c

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

DEFINITIONS

This source file includes following definitions.
  1. pfp_print
  2. me_print
  3. meq_print
  4. roq_print
  5. show
  6. reset_set
  7. a5xx_debugfs_init

   1 // SPDX-License-Identifier: GPL-2.0-only
   2 /* Copyright (c) 2016-2017 The Linux Foundation. All rights reserved.
   3  */
   4 
   5 #include <linux/types.h>
   6 #include <linux/debugfs.h>
   7 
   8 #include <drm/drm_debugfs.h>
   9 #include <drm/drm_file.h>
  10 #include <drm/drm_print.h>
  11 
  12 #include "a5xx_gpu.h"
  13 
  14 static int pfp_print(struct msm_gpu *gpu, struct drm_printer *p)
  15 {
  16         int i;
  17 
  18         drm_printf(p, "PFP state:\n");
  19 
  20         for (i = 0; i < 36; i++) {
  21                 gpu_write(gpu, REG_A5XX_CP_PFP_STAT_ADDR, i);
  22                 drm_printf(p, "  %02x: %08x\n", i,
  23                         gpu_read(gpu, REG_A5XX_CP_PFP_STAT_DATA));
  24         }
  25 
  26         return 0;
  27 }
  28 
  29 static int me_print(struct msm_gpu *gpu, struct drm_printer *p)
  30 {
  31         int i;
  32 
  33         drm_printf(p, "ME state:\n");
  34 
  35         for (i = 0; i < 29; i++) {
  36                 gpu_write(gpu, REG_A5XX_CP_ME_STAT_ADDR, i);
  37                 drm_printf(p, "  %02x: %08x\n", i,
  38                         gpu_read(gpu, REG_A5XX_CP_ME_STAT_DATA));
  39         }
  40 
  41         return 0;
  42 }
  43 
  44 static int meq_print(struct msm_gpu *gpu, struct drm_printer *p)
  45 {
  46         int i;
  47 
  48         drm_printf(p, "MEQ state:\n");
  49         gpu_write(gpu, REG_A5XX_CP_MEQ_DBG_ADDR, 0);
  50 
  51         for (i = 0; i < 64; i++) {
  52                 drm_printf(p, "  %02x: %08x\n", i,
  53                         gpu_read(gpu, REG_A5XX_CP_MEQ_DBG_DATA));
  54         }
  55 
  56         return 0;
  57 }
  58 
  59 static int roq_print(struct msm_gpu *gpu, struct drm_printer *p)
  60 {
  61         int i;
  62 
  63         drm_printf(p, "ROQ state:\n");
  64         gpu_write(gpu, REG_A5XX_CP_ROQ_DBG_ADDR, 0);
  65 
  66         for (i = 0; i < 512 / 4; i++) {
  67                 uint32_t val[4];
  68                 int j;
  69                 for (j = 0; j < 4; j++)
  70                         val[j] = gpu_read(gpu, REG_A5XX_CP_ROQ_DBG_DATA);
  71                 drm_printf(p, "  %02x: %08x %08x %08x %08x\n", i,
  72                         val[0], val[1], val[2], val[3]);
  73         }
  74 
  75         return 0;
  76 }
  77 
  78 static int show(struct seq_file *m, void *arg)
  79 {
  80         struct drm_info_node *node = (struct drm_info_node *) m->private;
  81         struct drm_device *dev = node->minor->dev;
  82         struct msm_drm_private *priv = dev->dev_private;
  83         struct drm_printer p = drm_seq_file_printer(m);
  84         int (*show)(struct msm_gpu *gpu, struct drm_printer *p) =
  85                 node->info_ent->data;
  86 
  87         return show(priv->gpu, &p);
  88 }
  89 
  90 #define ENT(n) { .name = #n, .show = show, .data = n ##_print }
  91 static struct drm_info_list a5xx_debugfs_list[] = {
  92         ENT(pfp),
  93         ENT(me),
  94         ENT(meq),
  95         ENT(roq),
  96 };
  97 
  98 /* for debugfs files that can be written to, we can't use drm helper: */
  99 static int
 100 reset_set(void *data, u64 val)
 101 {
 102         struct drm_device *dev = data;
 103         struct msm_drm_private *priv = dev->dev_private;
 104         struct msm_gpu *gpu = priv->gpu;
 105         struct adreno_gpu *adreno_gpu = to_adreno_gpu(gpu);
 106         struct a5xx_gpu *a5xx_gpu = to_a5xx_gpu(adreno_gpu);
 107 
 108         if (!capable(CAP_SYS_ADMIN))
 109                 return -EINVAL;
 110 
 111         /* TODO do we care about trying to make sure the GPU is idle?
 112          * Since this is just a debug feature limited to CAP_SYS_ADMIN,
 113          * maybe it is fine to let the user keep both pieces if they
 114          * try to reset an active GPU.
 115          */
 116 
 117         mutex_lock(&dev->struct_mutex);
 118 
 119         release_firmware(adreno_gpu->fw[ADRENO_FW_PM4]);
 120         adreno_gpu->fw[ADRENO_FW_PM4] = NULL;
 121 
 122         release_firmware(adreno_gpu->fw[ADRENO_FW_PFP]);
 123         adreno_gpu->fw[ADRENO_FW_PFP] = NULL;
 124 
 125         if (a5xx_gpu->pm4_bo) {
 126                 msm_gem_unpin_iova(a5xx_gpu->pm4_bo, gpu->aspace);
 127                 drm_gem_object_put(a5xx_gpu->pm4_bo);
 128                 a5xx_gpu->pm4_bo = NULL;
 129         }
 130 
 131         if (a5xx_gpu->pfp_bo) {
 132                 msm_gem_unpin_iova(a5xx_gpu->pfp_bo, gpu->aspace);
 133                 drm_gem_object_put(a5xx_gpu->pfp_bo);
 134                 a5xx_gpu->pfp_bo = NULL;
 135         }
 136 
 137         gpu->needs_hw_init = true;
 138 
 139         pm_runtime_get_sync(&gpu->pdev->dev);
 140         gpu->funcs->recover(gpu);
 141 
 142         pm_runtime_put_sync(&gpu->pdev->dev);
 143         mutex_unlock(&dev->struct_mutex);
 144 
 145         return 0;
 146 }
 147 
 148 DEFINE_SIMPLE_ATTRIBUTE(reset_fops, NULL, reset_set, "%llx\n");
 149 
 150 
 151 int a5xx_debugfs_init(struct msm_gpu *gpu, struct drm_minor *minor)
 152 {
 153         struct drm_device *dev;
 154         int ret;
 155 
 156         if (!minor)
 157                 return 0;
 158 
 159         dev = minor->dev;
 160 
 161         ret = drm_debugfs_create_files(a5xx_debugfs_list,
 162                         ARRAY_SIZE(a5xx_debugfs_list),
 163                         minor->debugfs_root, minor);
 164 
 165         if (ret) {
 166                 DRM_DEV_ERROR(dev->dev, "could not install a5xx_debugfs_list\n");
 167                 return ret;
 168         }
 169 
 170         debugfs_create_file("reset", S_IWUGO, minor->debugfs_root, dev,
 171                             &reset_fops);
 172 
 173         return 0;
 174 }

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