diff options
Diffstat (limited to 'drivers/gpu/drm/msm/adreno/adreno_gpu.c')
-rw-r--r-- | drivers/gpu/drm/msm/adreno/adreno_gpu.c | 39 |
1 files changed, 39 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"); |