video: tegra: dump current pushbuffer from channel debugger
authorMichael I. Gold <gold@nvidia.com>
Fri, 24 Sep 2010 18:41:51 +0000 (11:41 -0700)
committerErik Gilling <konkers@android.com>
Wed, 13 Oct 2010 01:07:15 +0000 (18:07 -0700)
Signed-off-by: Erik Gilling <konkers@android.com>
Change-Id: Ia14a2bad23ae1c6401755d413ffdc32c9f35b0fd

drivers/video/tegra/host/debug.c
drivers/video/tegra/host/nvhost_cdma.c
drivers/video/tegra/host/nvhost_cdma.h

index 29495c323775def9bb739f537e8bb7c4f21922d9..c1cfd6ee229cc3245f7e344a5f44da9493db558b 100644 (file)
@@ -100,6 +100,33 @@ static int nvhost_debug_handle_cmd(struct seq_file *s, u32 val, int *count)
        }
 }
 
+static void nvhost_debug_handle_word(struct seq_file *s, int *state, int *count,
+                                    unsigned long addr, int channel, u32 val)
+{
+       switch (*state) {
+       case NVHOST_DBG_STATE_CMD:
+               if (addr)
+                       seq_printf(s, "%d: %08x: %08x:", channel, addr, val);
+               else
+                       seq_printf(s, "%d: %08x:", channel, val);
+
+               *state = nvhost_debug_handle_cmd(s, val, count);
+               if (*state == NVHOST_DBG_STATE_DATA && *count == 0) {
+                       *state = NVHOST_DBG_STATE_CMD;
+                       seq_printf(s, "])\n");
+               }
+               break;
+
+       case NVHOST_DBG_STATE_DATA:
+               (*count)--;
+               seq_printf(s, "%08x%s", val, *count > 0 ? ", " : "])\n");
+               if (*count == 0)
+                       *state = NVHOST_DBG_STATE_CMD;
+               break;
+       }
+}
+
+
 static int nvhost_debug_show(struct seq_file *s, void *unused)
 {
        struct nvhost_master *m = s->private;
@@ -116,7 +143,8 @@ static int nvhost_debug_show(struct seq_file *s, void *unused)
                unsigned start, end;
                unsigned wr_ptr, rd_ptr;
                int state;
-               int count = 0;
+               int count;
+               u32 phys_addr, size;
 
                dmaput = readl(regs + HOST1X_CHANNEL_DMAPUT);
                dmaget = readl(regs + HOST1X_CHANNEL_DMAGET);
@@ -151,9 +179,35 @@ static int nvhost_debug_show(struct seq_file *s, void *unused)
                        break;
                }
 
+               nvhost_cdma_find_gather(&m->channels[i].cdma, dmaget, &phys_addr, &size);
+
+               /* If dmaget is in the pushbuffer (should always be?),
+                * check if we're executing a fetch, and if so dump
+                * it. */
+               if (size) {
+                       u32 offset = dmaget - m->channels[i].cdma.push_buffer.phys;
+                       u32 map_base = phys_addr & PAGE_MASK;
+                       u32 map_size = (size * 4 + PAGE_SIZE - 1) & PAGE_MASK;
+                       u32 map_offset = phys_addr - map_base;
+                       void *map_addr = ioremap_nocache(map_base, map_size);
+
+                       if (map_addr) {
+                               u32 ii;
+
+                               seq_printf(s, "\n%d: gather (%d words)\n", i, size);
+                               state = NVHOST_DBG_STATE_CMD;
+                               for (ii = 0; ii < size; ii++) {
+                                       val = readl(map_addr + map_offset + ii*sizeof(u32));
+                                       nvhost_debug_handle_word(s, &state, &count, phys_addr + ii, i, val);
+                               }
+                               iounmap(map_addr);
+                       }
+               }
+
                fifostat = readl(regs + HOST1X_CHANNEL_FIFOSTAT);
                if ((fifostat & 1 << 10) == 0 ) {
 
+                    seq_printf(s, "\n%d: fifo:\n", i);
                        writel(0x0, m->aperture + HOST1X_SYNC_CFPEEK_CTRL);
                        writel(1 << 31 | i << 16, m->aperture + HOST1X_SYNC_CFPEEK_CTRL);
                        rd_ptr = readl(m->aperture + HOST1X_SYNC_CFPEEK_PTRS) & 0x1ff;
@@ -169,24 +223,7 @@ static int nvhost_debug_show(struct seq_file *s, void *unused)
                                writel(1 << 31 | i << 16 | rd_ptr, m->aperture + HOST1X_SYNC_CFPEEK_CTRL);
                                val = readl(m->aperture + HOST1X_SYNC_CFPEEK_READ);
 
-                               switch (state) {
-                               case NVHOST_DBG_STATE_CMD:
-                                       seq_printf(s, "%d: %08x:", i, val);
-
-                                       state = nvhost_debug_handle_cmd(s, val, &count);
-                                       if (state == NVHOST_DBG_STATE_DATA && count == 0) {
-                                               state = NVHOST_DBG_STATE_CMD;
-                                               seq_printf(s, "])\n");
-                                       }
-                                       break;
-
-                               case NVHOST_DBG_STATE_DATA:
-                                       count--;
-                                       seq_printf(s, "%08x%s", val, count > 0 ? ", " : "])\n");
-                                       if (count == 0)
-                                               state = NVHOST_DBG_STATE_CMD;
-                                       break;
-                               }
+                               nvhost_debug_handle_word(s, &state, &count, 0, i, val);
 
                                if (rd_ptr == end)
                                        rd_ptr = start;
@@ -199,6 +236,7 @@ static int nvhost_debug_show(struct seq_file *s, void *unused)
                        if (state == NVHOST_DBG_STATE_DATA)
                                seq_printf(s, ", ...])\n");
                }
+
                seq_printf(s, "\n");
        }
 
index 4b90456696ad6092f926b050ebdde92010e79302..f27656bac07b314f0fadf9e2b823331649398c2a 100644 (file)
@@ -627,3 +627,24 @@ void nvhost_cdma_flush(struct nvhost_cdma *cdma)
        }
        mutex_unlock(&cdma->lock);
 }
+
+/**
+ * Find the currently executing gather in the push buffer and return
+ * its physical address and size.
+ */
+void nvhost_cdma_find_gather(struct nvhost_cdma *cdma, u32 dmaget, u32 *addr, u32 *size)
+{
+       u32 offset = dmaget - cdma->push_buffer.phys;
+
+       *addr = *size = 0;
+
+       if (offset >= 8 && offset < cdma->push_buffer.cur) {
+               u32 *p = cdma->push_buffer.mapped + (offset - 8) / 4;
+
+               /* Make sure we have a gather */
+               if ((p[0] >> 28) == 6) {
+                       *addr = p[1];
+                       *size = p[0] & 0x3fff;
+               }
+       }
+}
index 77493abe0e271bfe84cfca31e1d74e8c639b80df..a7f17d0413d5025c5cd0dc564acf7829644a2c27 100644 (file)
@@ -97,5 +97,7 @@ void  nvhost_cdma_end(struct nvmap_client *user_nvmap,
                        struct nvmap_handle **handles, unsigned int nr_handles);
 void   nvhost_cdma_update(struct nvhost_cdma *cdma);
 void   nvhost_cdma_flush(struct nvhost_cdma *cdma);
+void    nvhost_cdma_find_gather(struct nvhost_cdma *cdma, u32 dmaget,
+                u32 *addr, u32 *size);
 
 #endif