summaryrefslogtreecommitdiff
path: root/drivers/video/tegra/host/host1x/host1x_debug.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/video/tegra/host/host1x/host1x_debug.c')
-rw-r--r--drivers/video/tegra/host/host1x/host1x_debug.c132
1 files changed, 74 insertions, 58 deletions
diff --git a/drivers/video/tegra/host/host1x/host1x_debug.c b/drivers/video/tegra/host/host1x/host1x_debug.c
index 76483d82528b..7de342298c4d 100644
--- a/drivers/video/tegra/host/host1x/host1x_debug.c
+++ b/drivers/video/tegra/host/host1x/host1x_debug.c
@@ -28,8 +28,8 @@
#include "host1x_hardware.h"
#include "nvhost_cdma.h"
#include "nvhost_channel.h"
-#include "../../nvmap/nvmap.h"
#include "host1x_cdma.h"
+#include "nvhost_job.h"
#define NVHOST_DEBUG_MAX_PAGE_OFFSET 102400
@@ -160,6 +160,34 @@ static void show_channel_word(struct output *o, int *state, int *count,
}
}
+static void do_show_channel_gather(struct output *o,
+ phys_addr_t phys_addr,
+ u32 words, struct nvhost_cdma *cdma,
+ phys_addr_t pin_addr, u32 *map_addr)
+{
+ /* Map dmaget cursor to corresponding nvmap_handle */
+ u32 offset;
+ int state, count, i;
+
+ offset = phys_addr - pin_addr;
+ /*
+ * Sometimes we're given different hardware address to the same
+ * page - in these cases the offset will get an invalid number and
+ * we just have to bail out.
+ */
+ if (offset > NVHOST_DEBUG_MAX_PAGE_OFFSET) {
+ nvhost_debug_output(o, "[address mismatch]\n");
+ } else {
+ /* GATHER buffer starts always with commands */
+ state = NVHOST_DBG_STATE_CMD;
+ for (i = 0; i < words; i++)
+ show_channel_word(o, &state, &count,
+ phys_addr + i * 4,
+ *(map_addr + offset/4 + i),
+ cdma);
+ }
+}
+
static void show_channel_gather(struct output *o, u32 addr,
phys_addr_t phys_addr,
u32 words, struct nvhost_cdma *cdma)
@@ -169,81 +197,36 @@ static void show_channel_gather(struct output *o, u32 addr,
struct push_buffer *pb = &cdma->push_buffer;
u32 cur = addr - pb->phys;
struct nvmap_client_handle *nvmap = &pb->nvmap[cur/8];
- struct nvmap_handle_ref ref;
u32 *map_addr, offset;
phys_addr_t pin_addr;
- int state, count, i;
- if (!nvmap->handle || !nvmap->client
- || atomic_read(&nvmap->handle->ref) < 1) {
+ if (!nvmap || !nvmap->handle || !nvmap->client) {
nvhost_debug_output(o, "[already deallocated]\n");
return;
}
- /* Create a fake nvmap_handle_ref - nvmap requires it
- * but accesses only the first field - nvmap_handle */
- ref.handle = nvmap->handle;
-
- map_addr = nvmap_mmap(&ref);
+ map_addr = nvmap_mmap(nvmap->handle);
if (!map_addr) {
nvhost_debug_output(o, "[could not mmap]\n");
return;
}
/* Get base address from nvmap */
- pin_addr = nvmap_pin(nvmap->client, &ref);
+ pin_addr = nvmap_pin(nvmap->client, nvmap->handle);
if (IS_ERR_VALUE(pin_addr)) {
nvhost_debug_output(o, "[couldn't pin]\n");
- nvmap_munmap(&ref, map_addr);
+ nvmap_munmap(nvmap->handle, map_addr);
return;
}
offset = phys_addr - pin_addr;
- /*
- * Sometimes we're given different hardware address to the same
- * page - in these cases the offset will get an invalid number and
- * we just have to bail out.
- */
- if (offset > NVHOST_DEBUG_MAX_PAGE_OFFSET) {
- nvhost_debug_output(o, "[address mismatch]\n");
- } else {
- /* GATHER buffer starts always with commands */
- state = NVHOST_DBG_STATE_CMD;
- for (i = 0; i < words; i++)
- show_channel_word(o, &state, &count,
- phys_addr + i * 4,
- *(map_addr + offset/4 + i),
- cdma);
- }
- nvmap_unpin(nvmap->client, &ref);
- nvmap_munmap(&ref, map_addr);
+ do_show_channel_gather(o, phys_addr, words, cdma,
+ pin_addr, map_addr);
+ nvmap_unpin(nvmap->client, nvmap->handle);
+ nvmap_munmap(nvmap->handle, map_addr);
#endif
}
-static void show_channel_pair(struct output *o, u32 addr,
- u32 w0, u32 w1, struct nvhost_cdma *cdma)
-{
- int state = NVHOST_DBG_STATE_CMD;
- int count;
-
- show_channel_word(o, &state, &count, addr, w0, cdma);
- show_channel_word(o, &state, &count, addr+4, w1, cdma);
-}
-
-/**
- * Retrieve the op pair at a slot offset from a DMA address
- */
-static void cdma_peek(struct nvhost_cdma *cdma,
- u32 dmaget, int slot, u32 *out)
-{
- u32 offset = dmaget - cdma->push_buffer.phys;
- u32 *p = cdma->push_buffer.mapped;
-
- offset = ((offset + slot * 8) & (PUSH_BUFFER_SIZE - 1)) >> 2;
- out[0] = p[offset];
- out[1] = p[offset + 1];
-}
-
u32 previous_oppair(struct nvhost_cdma *cdma, u32 cur)
{
u32 pb = cdma->push_buffer.phys;
@@ -253,6 +236,42 @@ u32 previous_oppair(struct nvhost_cdma *cdma, u32 cur)
return prev;
}
+void show_channel_gathers(struct output *o, struct nvhost_cdma *cdma)
+{
+ struct nvhost_job *job;
+
+ list_for_each_entry(job, &cdma->sync_queue, list) {
+ int i;
+ nvhost_debug_output(o, "\n%p: JOB, syncpt_id=%d, syncpt_val=%d,"
+ " first_get=%08x, timeout=%d, ctx=%p,"
+ " num_slots=%d, num_handles=%d\n",
+ job,
+ job->syncpt_id,
+ job->syncpt_end,
+ job->first_get,
+ job->timeout,
+ job->hwctx,
+ job->num_slots,
+ job->num_unpins);
+
+ for (i = 0; i < job->num_gathers; i++) {
+ struct nvhost_job_gather *g = &job->gathers[i];
+ u32 *mapped = nvmap_mmap(g->ref);
+ if (!mapped) {
+ nvhost_debug_output(o, "[could not mmap]\n");
+ continue;
+ }
+
+ nvhost_debug_output(o, " GATHER at %08x, %d words\n",
+ g->mem, g->words);
+
+ do_show_channel_gather(o, g->mem + g->offset,
+ g->words, cdma, g->mem, mapped);
+ nvmap_munmap(g->ref, mapped);
+ }
+ }
+}
+
static void t20_debug_show_channel_cdma(struct nvhost_master *m,
struct nvhost_channel *ch, struct output *o, int chid)
{
@@ -261,7 +280,6 @@ static void t20_debug_show_channel_cdma(struct nvhost_master *m,
u32 dmaput, dmaget, dmactrl;
u32 cbstat, cbread;
u32 val, base, baseval;
- u32 pbw[2];
dmaput = readl(channel->aperture + HOST1X_CHANNEL_DMAPUT);
dmaget = readl(channel->aperture + HOST1X_CHANNEL_DMAGET);
@@ -310,9 +328,7 @@ static void t20_debug_show_channel_cdma(struct nvhost_master *m,
dmaput, dmaget, dmactrl);
nvhost_debug_output(o, "CBREAD %08x, CBSTAT %08x\n", cbread, cbstat);
- cdma_peek(cdma, dmaget, -1, pbw);
- show_channel_pair(o, previous_oppair(cdma, dmaget),
- pbw[0], pbw[1], &channel->cdma);
+ show_channel_gathers(o, cdma);
nvhost_debug_output(o, "\n");
}