video: tegra: dump host state when timing out on suspend
authorErik Gilling <konkers@android.com>
Mon, 24 Jan 2011 20:35:11 +0000 (12:35 -0800)
committerErik Gilling <konkers@android.com>
Mon, 24 Jan 2011 20:37:38 +0000 (12:37 -0800)
Change-Id: I718fb071ac74f5a051a7d5b9fcdd782163ed48b6
Signed-off-by: Erik Gilling <konkers@android.com>
drivers/video/tegra/host/debug.c
drivers/video/tegra/host/dev.h
drivers/video/tegra/host/nvhost_acm.c

index c1cfd6ee229cc3245f7e344a5f44da9493db558b..d533310e3999085b3653ff0f5b2ad2a906a6dd3d 100644 (file)
@@ -22,7 +22,7 @@
 
 #include "dev.h"
 
-#ifdef CONFIG_DEBUG_FS
+static struct nvhost_master *debug_master;
 
 enum {
        NVHOST_DBG_STATE_CMD = 0,
@@ -134,6 +134,28 @@ static int nvhost_debug_show(struct seq_file *s, void *unused)
 
        nvhost_module_busy(&m->mod);
 
+       seq_printf(s, "---- mlocks ----\n");
+       for (i = 0; i < NV_HOST1X_NB_MLOCKS; i++) {
+               u32 owner = readl(m->sync_aperture + HOST1X_SYNC_MLOCK_OWNER_0 + i * 4);
+               if (owner & 0x1)
+                       seq_printf(s, "%d: locked by channel %d\n", i, (owner >> 8) * 0xff);
+               else if (owner & 0x2)
+                       seq_printf(s, "%d: locked by cpu\n", i);
+               else
+                       seq_printf(s, "%d: unlocked\n", i);
+       }
+       seq_printf(s, "\n---- syncpts ----\n");
+       for (i = 0; i < NV_HOST1X_SYNCPT_NB_PTS; i++) {
+               u32 max = nvhost_syncpt_read_max(&m->syncpt, i);
+               if (!max)
+                       continue;
+               seq_printf(s, "id %d (%s) min %d max %d\n",
+                       i, nvhost_syncpt_name(i),
+                       nvhost_syncpt_update_min(&m->syncpt, i), max);
+
+       }
+
+       seq_printf(s, "\n---- channels ----\n");
        for (i = 0; i < NVHOST_NUMCHANNELS; i++) {
                void __iomem *regs = m->channels[i].aperture;
                u32 dmaput, dmaget, dmactrl;
@@ -152,15 +174,18 @@ static int nvhost_debug_show(struct seq_file *s, void *unused)
                cbread = readl(m->aperture + HOST1X_SYNC_CBREAD(i));
                cbstat = readl(m->aperture + HOST1X_SYNC_CBSTAT(i));
 
+               seq_printf(s, "%d-%s (%d): ", i, m->channels[i].mod.name,
+                          m->channels[i].mod.refcount);
+
                if (dmactrl != 0x0 || !m->channels[i].cdma.push_buffer.mapped) {
-                       seq_printf(s, "%d: inactive\n\n", i);
+                       seq_printf(s, "inactive\n\n");
                        continue;
                }
 
                switch (cbstat) {
                case 0x00010008:
-                       seq_printf(s, "%d: waiting on syncpt %d val %d\n",
-                                  i, cbread >> 24, cbread & 0xffffff);
+                       seq_printf(s, "waiting on syncpt %d val %d\n",
+                                  cbread >> 24, cbread & 0xffffff);
                        break;
 
                case 0x00010009:
@@ -169,13 +194,13 @@ static int nvhost_debug_show(struct seq_file *s, void *unused)
                        val = readl(m->aperture + HOST1X_SYNC_SYNCPT_BASE(base)) & 0xffff;
                        val += cbread & 0xffff;
 
-                       seq_printf(s, "%d: waiting on syncpt %d val %d\n",
-                                  i, cbread >> 24, val);
+                       seq_printf(s, "waiting on syncpt %d val %d\n",
+                                  cbread >> 24, val);
                        break;
 
                default:
-                       seq_printf(s, "%d: active class %02x, offset %04x, val %08x\n",
-                                  i, cbstat >> 16, cbstat & 0xffff, cbread);
+                       seq_printf(s, "active class %02x, offset %04x, val %08x\n",
+                                  cbstat >> 16, cbstat & 0xffff, cbread);
                        break;
                }
 
@@ -244,6 +269,7 @@ static int nvhost_debug_show(struct seq_file *s, void *unused)
        return 0;
 }
 
+#ifdef CONFIG_DEBUG_FS
 
 static int nvhost_debug_open(struct inode *inode, struct file *file)
 {
@@ -259,12 +285,44 @@ static const struct file_operations nvhost_debug_fops = {
 
 void nvhost_debug_init(struct nvhost_master *master)
 {
+       debug_master = master;
        debugfs_create_file("tegra_host", S_IRUGO, NULL, master, &nvhost_debug_fops);
 }
 #else
-void nvhost_debug_add(struct nvhost_master *master)
+void nvhost_debug_init(struct nvhost_master *master)
 {
+       debug_master = master;
 }
 
 #endif
 
+static char nvhost_debug_dump_buff[16 * 1024];
+
+void nvhost_debug_dump(void)
+{
+       struct seq_file s;
+       int i;
+       char c;
+
+       memset(&s, 0x0, sizeof(s));
+
+       s.buf = nvhost_debug_dump_buff;
+       s.size = sizeof(nvhost_debug_dump_buff);
+       s.private = debug_master;
+
+       nvhost_debug_show(&s, NULL);
+
+       i = 0;
+       while (i < s.count ) {
+               if ((s.count - i) > 256) {
+                       c = s.buf[i + 256];
+                       s.buf[i + 256] = 0;
+                       printk("%s", s.buf + i);
+                       s.buf[i + 256] = c;
+               } else {
+                       printk("%s", s.buf + i);
+               }
+               i += 256;
+       }
+}
+
index ae9847c2bd7490456752d99e08fde2067d9c5aa6..4f71ff5d9a9dcf76a2f5435e1c194c2dfef8bdbd 100644 (file)
@@ -48,5 +48,6 @@ struct nvhost_master {
 };
 
 void nvhost_debug_init(struct nvhost_master *master);
+void nvhost_debug_dump(void);
 
 #endif
index cf542be8a6453fe3d04fdeecced520bcfd6a0547..ef8f1ea2c13a9472a5b4010fddafbc0dd98c5402 100644 (file)
@@ -28,6 +28,8 @@
 #include <mach/powergate.h>
 #include <mach/clk.h>
 
+#include "dev.h"
+
 #define ACM_TIMEOUT 1*HZ
 
 #define DISABLE_3D_POWERGATING
@@ -194,7 +196,12 @@ static int is_module_idle(struct nvhost_module *mod)
 
 void nvhost_module_suspend(struct nvhost_module *mod)
 {
-       wait_event(mod->idle, is_module_idle(mod));
+       int ret;
+
+       ret = wait_event_timeout(mod->idle, is_module_idle(mod),
+                          ACM_TIMEOUT + msecs_to_jiffies(500));
+       if (ret == 0)
+               nvhost_debug_dump();
        flush_delayed_work(&mod->powerdown);
        BUG_ON(mod->powered);
 }