summaryrefslogtreecommitdiff
path: root/drivers/gpu/drm/msm/adreno/adreno_gpu.c
diff options
context:
space:
mode:
authorJordan Crouse <jcrouse@codeaurora.org>2018-07-24 10:33:24 -0600
committerRob Clark <robdclark@gmail.com>2018-07-30 08:49:45 -0400
commite00e473d9817e03cddbaf181a491c42ae8373482 (patch)
tree9637b302c3de0065110d7be403cb63e6d78daeb5 /drivers/gpu/drm/msm/adreno/adreno_gpu.c
parent5dc634bdbfd6dd9bdf98bce0d6f64878e1d47b1f (diff)
drm/msm/gpu: Capture the state of the GPU
Add the infrastructure to capture the current state of the GPU and store it in memory so that it can be dumped later. For now grab the same basic ringbuffer information and registers that are provided by the debugfs 'gpu' node but obviously this should be extended to capture a much larger set of GPU information. Signed-off-by: Jordan Crouse <jcrouse@codeaurora.org> Signed-off-by: Rob Clark <robdclark@gmail.com>
Diffstat (limited to 'drivers/gpu/drm/msm/adreno/adreno_gpu.c')
-rw-r--r--drivers/gpu/drm/msm/adreno/adreno_gpu.c55
1 files changed, 55 insertions, 0 deletions
diff --git a/drivers/gpu/drm/msm/adreno/adreno_gpu.c b/drivers/gpu/drm/msm/adreno/adreno_gpu.c
index bcbf9f2a29f9..4286a539f40a 100644
--- a/drivers/gpu/drm/msm/adreno/adreno_gpu.c
+++ b/drivers/gpu/drm/msm/adreno/adreno_gpu.c
@@ -368,6 +368,61 @@ bool adreno_idle(struct msm_gpu *gpu, struct msm_ringbuffer *ring)
return false;
}
+struct msm_gpu_state *adreno_gpu_state_get(struct msm_gpu *gpu)
+{
+ struct adreno_gpu *adreno_gpu = to_adreno_gpu(gpu);
+ struct msm_gpu_state *state;
+ int i, count = 0;
+
+ state = kzalloc(sizeof(*state), GFP_KERNEL);
+ if (!state)
+ return ERR_PTR(-ENOMEM);
+
+ do_gettimeofday(&state->time);
+
+ for (i = 0; i < gpu->nr_rings; i++) {
+ state->ring[i].fence = gpu->rb[i]->memptrs->fence;
+ state->ring[i].iova = gpu->rb[i]->iova;
+ state->ring[i].seqno = gpu->rb[i]->seqno;
+ state->ring[i].rptr = get_rptr(adreno_gpu, gpu->rb[i]);
+ state->ring[i].wptr = get_wptr(gpu->rb[i]);
+ }
+
+ /* Count the number of registers */
+ for (i = 0; adreno_gpu->registers[i] != ~0; i += 2)
+ count += adreno_gpu->registers[i + 1] -
+ adreno_gpu->registers[i] + 1;
+
+ state->registers = kcalloc(count * 2, sizeof(u32), GFP_KERNEL);
+ if (state->registers) {
+ int pos = 0;
+
+ for (i = 0; adreno_gpu->registers[i] != ~0; i += 2) {
+ u32 start = adreno_gpu->registers[i];
+ u32 end = adreno_gpu->registers[i + 1];
+ u32 addr;
+
+ for (addr = start; addr <= end; addr++) {
+ state->registers[pos++] = addr;
+ state->registers[pos++] = gpu_read(gpu, addr);
+ }
+ }
+
+ state->nr_registers = count;
+ }
+
+ return state;
+}
+
+void adreno_gpu_state_put(struct msm_gpu_state *state)
+{
+ if (IS_ERR_OR_NULL(state))
+ return;
+
+ kfree(state->registers);
+ kfree(state);
+}
+
#ifdef CONFIG_DEBUG_FS
void adreno_show(struct msm_gpu *gpu, struct seq_file *m)
{