summaryrefslogtreecommitdiff
path: root/drivers/gpu/drm/msm/msm_gpu.h
diff options
context:
space:
mode:
authorJordan Crouse <jcrouse@codeaurora.org>2018-07-24 19:33:27 +0300
committerRob Clark <robdclark@gmail.com>2018-07-30 15:49:56 +0300
commitc0fec7f562ec76404ef0f074a89113a703587f3d (patch)
treed88efd150b3c010d6d1ed8c94f26f347c46228d4 /drivers/gpu/drm/msm/msm_gpu.h
parent65a3c2748e882da03102369edb6991e1dd88456e (diff)
downloadlinux-c0fec7f562ec76404ef0f074a89113a703587f3d.tar.xz
drm/msm/gpu: Capture the GPU state on a GPU hang
Capture the GPU state on a GPU hang and store it for later playback via the devcoredump facility. Only one crash state is stored at a time on the assumption that the first hang is usually the most interesting. The existing crash state can be cleared after capturing it and then a new one will be captured on the next hang. Signed-off-by: Jordan Crouse <jcrouse@codeaurora.org> Signed-off-by: Rob Clark <robdclark@gmail.com>
Diffstat (limited to 'drivers/gpu/drm/msm/msm_gpu.h')
-rw-r--r--drivers/gpu/drm/msm/msm_gpu.h38
1 files changed, 36 insertions, 2 deletions
diff --git a/drivers/gpu/drm/msm/msm_gpu.h b/drivers/gpu/drm/msm/msm_gpu.h
index d204eca8518e..b1cb44922441 100644
--- a/drivers/gpu/drm/msm/msm_gpu.h
+++ b/drivers/gpu/drm/msm/msm_gpu.h
@@ -66,13 +66,13 @@ struct msm_gpu_funcs {
#ifdef CONFIG_DEBUG_FS
/* show GPU status in debugfs: */
void (*show)(struct msm_gpu *gpu, struct msm_gpu_state *state,
- struct seq_file *m);
+ struct drm_printer *p);
/* for generation specific debugfs: */
int (*debugfs_init)(struct msm_gpu *gpu, struct drm_minor *minor);
#endif
int (*gpu_busy)(struct msm_gpu *gpu, uint64_t *value);
struct msm_gpu_state *(*gpu_state_get)(struct msm_gpu *gpu);
- void (*gpu_state_put)(struct msm_gpu_state *state);
+ int (*gpu_state_put)(struct msm_gpu_state *state);
};
struct msm_gpu {
@@ -133,6 +133,8 @@ struct msm_gpu {
u64 busy_cycles;
ktime_t time;
} devfreq;
+
+ struct msm_gpu_state *crashstate;
};
/* It turns out that all targets use the same ringbuffer size */
@@ -180,6 +182,7 @@ struct msm_gpu_submitqueue {
};
struct msm_gpu_state {
+ struct kref ref;
struct timeval time;
struct {
@@ -194,6 +197,9 @@ struct msm_gpu_state {
u32 *registers;
u32 rbbm_status;
+
+ char *comm;
+ char *cmd;
};
static inline void gpu_write(struct msm_gpu *gpu, u32 reg, u32 data)
@@ -275,4 +281,32 @@ static inline void msm_submitqueue_put(struct msm_gpu_submitqueue *queue)
kref_put(&queue->ref, msm_submitqueue_destroy);
}
+static inline struct msm_gpu_state *msm_gpu_crashstate_get(struct msm_gpu *gpu)
+{
+ struct msm_gpu_state *state = NULL;
+
+ mutex_lock(&gpu->dev->struct_mutex);
+
+ if (gpu->crashstate) {
+ kref_get(&gpu->crashstate->ref);
+ state = gpu->crashstate;
+ }
+
+ mutex_unlock(&gpu->dev->struct_mutex);
+
+ return state;
+}
+
+static inline void msm_gpu_crashstate_put(struct msm_gpu *gpu)
+{
+ mutex_lock(&gpu->dev->struct_mutex);
+
+ if (gpu->crashstate) {
+ if (gpu->funcs->gpu_state_put(gpu->crashstate))
+ gpu->crashstate = NULL;
+ }
+
+ mutex_unlock(&gpu->dev->struct_mutex);
+}
+
#endif /* __MSM_GPU_H__ */