summaryrefslogtreecommitdiffstats
path: root/drivers/gpu/drm/msm
diff options
context:
space:
mode:
authorJordan Crouse <jcrouse@codeaurora.org>2018-07-24 10:33:29 -0600
committerRob Clark <robdclark@gmail.com>2018-07-30 08:50:03 -0400
commit43a56687d15db09f3cf7b9d53b182bdef86c17c0 (patch)
treebb5549cd2f648b7d8a1515b30604ca8744e7ee66 /drivers/gpu/drm/msm
parentbcf1d9fa5d03c1e86733411b5dc3a76ba7d75e6e (diff)
drm/msm/adreno: Add ringbuffer data to the GPU state
Add the contents of each ringbuffer to the GPU state and dump the data in the crash file encoded with ascii85. To save space only the used portions of the ringbuffer are dumped. Signed-off-by: Jordan Crouse <jcrouse@codeaurora.org> Signed-off-by: Rob Clark <robdclark@gmail.com>
Diffstat (limited to 'drivers/gpu/drm/msm')
-rw-r--r--drivers/gpu/drm/msm/adreno/adreno_gpu.c39
-rw-r--r--drivers/gpu/drm/msm/msm_gpu.h2
2 files changed, 41 insertions, 0 deletions
diff --git a/drivers/gpu/drm/msm/adreno/adreno_gpu.c b/drivers/gpu/drm/msm/adreno/adreno_gpu.c
index c7a998d9dc85..808d4fc9c4a1 100644
--- a/drivers/gpu/drm/msm/adreno/adreno_gpu.c
+++ b/drivers/gpu/drm/msm/adreno/adreno_gpu.c
@@ -17,6 +17,7 @@
* this program. If not, see <http://www.gnu.org/licenses/>.
*/
+#include <linux/ascii85.h>
#include <linux/pm_opp.h>
#include "adreno_gpu.h"
#include "msm_gem.h"
@@ -383,11 +384,29 @@ struct msm_gpu_state *adreno_gpu_state_get(struct msm_gpu *gpu)
do_gettimeofday(&state->time);
for (i = 0; i < gpu->nr_rings; i++) {
+ int size = 0, j;
+
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]);
+
+ /* Copy at least 'wptr' dwords of the data */
+ size = state->ring[i].wptr;
+
+ /* After wptr find the last non zero dword to save space */
+ for (j = state->ring[i].wptr; j < MSM_GPU_RINGBUFFER_SZ >> 2; j++)
+ if (gpu->rb[i]->start[j])
+ size = j + 1;
+
+ if (size) {
+ state->ring[i].data = kmalloc(size << 2, GFP_KERNEL);
+ if (state->ring[i].data) {
+ memcpy(state->ring[i].data, gpu->rb[i]->start, size << 2);
+ state->ring[i].data_size = size << 2;
+ }
+ }
}
/* Count the number of registers */
@@ -418,9 +437,13 @@ struct msm_gpu_state *adreno_gpu_state_get(struct msm_gpu *gpu)
static void adreno_gpu_state_destroy(struct kref *kref)
{
+ int i;
struct msm_gpu_state *state = container_of(kref,
struct msm_gpu_state, ref);
+ for (i = 0; i < ARRAY_SIZE(state->ring); i++)
+ kfree(state->ring[i].data);
+
kfree(state->comm);
kfree(state->cmd);
kfree(state->registers);
@@ -461,6 +484,22 @@ void adreno_show(struct msm_gpu *gpu, struct msm_gpu_state *state,
drm_printf(p, " retired-fence: %d\n", state->ring[i].fence);
drm_printf(p, " rptr: %d\n", state->ring[i].rptr);
drm_printf(p, " wptr: %d\n", state->ring[i].wptr);
+ drm_printf(p, " size: %d\n", MSM_GPU_RINGBUFFER_SZ);
+
+ if (state->ring[i].data && state->ring[i].data_size) {
+ u32 *ptr = (u32 *) state->ring[i].data;
+ char out[ASCII85_BUFSZ];
+ long len = ascii85_encode_len(state->ring[i].data_size);
+ int j;
+
+ drm_printf(p, " data: !!ascii85 |\n");
+ drm_printf(p, " ");
+
+ for (j = 0; j < len; j++)
+ drm_printf(p, ascii85_encode(ptr[j], out));
+
+ drm_printf(p, "\n");
+ }
}
drm_puts(p, "registers:\n");
diff --git a/drivers/gpu/drm/msm/msm_gpu.h b/drivers/gpu/drm/msm/msm_gpu.h
index b1cb44922441..878090b57e90 100644
--- a/drivers/gpu/drm/msm/msm_gpu.h
+++ b/drivers/gpu/drm/msm/msm_gpu.h
@@ -191,6 +191,8 @@ struct msm_gpu_state {
u32 seqno;
u32 rptr;
u32 wptr;
+ void *data;
+ int data_size;
} ring[MSM_GPU_MAX_RINGS];
int nr_registers;