diff options
author | Erik Gilling <konkers@android.com> | 2011-01-24 12:35:11 -0800 |
---|---|---|
committer | Erik Gilling <konkers@android.com> | 2011-01-24 12:37:38 -0800 |
commit | 28b85f11c6dc65ac2c70f159a8210a4dd9554881 (patch) | |
tree | c1e10d428980c4b539168384fa5df72a4d0aa915 /drivers | |
parent | 3edd9628c0206b4239e2bcec977ca3b4e618a199 (diff) |
video: tegra: dump host state when timing out on suspend
Change-Id: I718fb071ac74f5a051a7d5b9fcdd782163ed48b6
Signed-off-by: Erik Gilling <konkers@android.com>
Diffstat (limited to 'drivers')
-rw-r--r-- | drivers/video/tegra/host/debug.c | 76 | ||||
-rw-r--r-- | drivers/video/tegra/host/dev.h | 1 | ||||
-rw-r--r-- | drivers/video/tegra/host/nvhost_acm.c | 9 |
3 files changed, 76 insertions, 10 deletions
diff --git a/drivers/video/tegra/host/debug.c b/drivers/video/tegra/host/debug.c index c1cfd6ee229c..d533310e3999 100644 --- a/drivers/video/tegra/host/debug.c +++ b/drivers/video/tegra/host/debug.c @@ -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; + } +} + diff --git a/drivers/video/tegra/host/dev.h b/drivers/video/tegra/host/dev.h index ae9847c2bd74..4f71ff5d9a9d 100644 --- a/drivers/video/tegra/host/dev.h +++ b/drivers/video/tegra/host/dev.h @@ -48,5 +48,6 @@ struct nvhost_master { }; void nvhost_debug_init(struct nvhost_master *master); +void nvhost_debug_dump(void); #endif diff --git a/drivers/video/tegra/host/nvhost_acm.c b/drivers/video/tegra/host/nvhost_acm.c index cf542be8a645..ef8f1ea2c13a 100644 --- a/drivers/video/tegra/host/nvhost_acm.c +++ b/drivers/video/tegra/host/nvhost_acm.c @@ -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); } |