Commit 43a56687 authored by Jordan Crouse's avatar Jordan Crouse Committed by Rob Clark

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: default avatarJordan Crouse <jcrouse@codeaurora.org>
Signed-off-by: default avatarRob Clark <robdclark@gmail.com>
parent bcf1d9fa
...@@ -59,6 +59,13 @@ ringbuffer ...@@ -59,6 +59,13 @@ ringbuffer
wptr wptr
The current write pointer (wptr) for the ringbuffer. The current write pointer (wptr) for the ringbuffer.
size
Maximum size of the ringbuffer programmed in the hardware.
data
The contents of the ring encoded as ascii85. Only the used
portions of the ring will be printed.
registers registers
Set of registers values. Each entry is on its own line enclosed Set of registers values. Each entry is on its own line enclosed
by brackets { }. by brackets { }.
......
...@@ -17,6 +17,7 @@ ...@@ -17,6 +17,7 @@
* this program. If not, see <http://www.gnu.org/licenses/>. * this program. If not, see <http://www.gnu.org/licenses/>.
*/ */
#include <linux/ascii85.h>
#include <linux/pm_opp.h> #include <linux/pm_opp.h>
#include "adreno_gpu.h" #include "adreno_gpu.h"
#include "msm_gem.h" #include "msm_gem.h"
...@@ -383,11 +384,29 @@ struct msm_gpu_state *adreno_gpu_state_get(struct msm_gpu *gpu) ...@@ -383,11 +384,29 @@ struct msm_gpu_state *adreno_gpu_state_get(struct msm_gpu *gpu)
do_gettimeofday(&state->time); do_gettimeofday(&state->time);
for (i = 0; i < gpu->nr_rings; i++) { for (i = 0; i < gpu->nr_rings; i++) {
int size = 0, j;
state->ring[i].fence = gpu->rb[i]->memptrs->fence; state->ring[i].fence = gpu->rb[i]->memptrs->fence;
state->ring[i].iova = gpu->rb[i]->iova; state->ring[i].iova = gpu->rb[i]->iova;
state->ring[i].seqno = gpu->rb[i]->seqno; state->ring[i].seqno = gpu->rb[i]->seqno;
state->ring[i].rptr = get_rptr(adreno_gpu, gpu->rb[i]); state->ring[i].rptr = get_rptr(adreno_gpu, gpu->rb[i]);
state->ring[i].wptr = get_wptr(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 */ /* Count the number of registers */
...@@ -418,9 +437,13 @@ struct msm_gpu_state *adreno_gpu_state_get(struct msm_gpu *gpu) ...@@ -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) static void adreno_gpu_state_destroy(struct kref *kref)
{ {
int i;
struct msm_gpu_state *state = container_of(kref, struct msm_gpu_state *state = container_of(kref,
struct msm_gpu_state, ref); struct msm_gpu_state, ref);
for (i = 0; i < ARRAY_SIZE(state->ring); i++)
kfree(state->ring[i].data);
kfree(state->comm); kfree(state->comm);
kfree(state->cmd); kfree(state->cmd);
kfree(state->registers); kfree(state->registers);
...@@ -461,6 +484,22 @@ void adreno_show(struct msm_gpu *gpu, struct msm_gpu_state *state, ...@@ -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, " retired-fence: %d\n", state->ring[i].fence);
drm_printf(p, " rptr: %d\n", state->ring[i].rptr); drm_printf(p, " rptr: %d\n", state->ring[i].rptr);
drm_printf(p, " wptr: %d\n", state->ring[i].wptr); 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"); drm_puts(p, "registers:\n");
......
...@@ -191,6 +191,8 @@ struct msm_gpu_state { ...@@ -191,6 +191,8 @@ struct msm_gpu_state {
u32 seqno; u32 seqno;
u32 rptr; u32 rptr;
u32 wptr; u32 wptr;
void *data;
int data_size;
} ring[MSM_GPU_MAX_RINGS]; } ring[MSM_GPU_MAX_RINGS];
int nr_registers; int nr_registers;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment