summaryrefslogtreecommitdiff
path: root/drivers
diff options
context:
space:
mode:
authorTerje Bergstrom <tbergstrom@nvidia.com>2011-10-24 15:08:43 +0300
committerVarun Colbert <vcolbert@nvidia.com>2011-11-07 13:50:29 -0800
commit420a73b658b5c2236f3e1433a61304c08cfdf1d3 (patch)
tree9cf4860ef2c21afaee268af4d97a0c131555f32f /drivers
parentb8d1c4365628577236106a7ec7029f128629d530 (diff)
video: tegra: host: Add extra syncpt debug info
Add extra syncpt debug info and kernel panic when device stuck waiting at syncpts. Tested by inducing syncpt stuck-wait by bypassing nvhost_syncpt- _cpu_incr. Bug 822880 Bug 820056 Bug 818058 Bug 810463 Bug 803452 Reviewed-on: http://git-master/r/60206 (cherry picked from commit e73caae974f43ac5bf30589fc3cbc1fa66df926e) Change-Id: Ia9a99cad17cbf49bf2fb860f783d0e94de0cec8e Reviewed-on: http://git-master/r/62355 Reviewed-by: Terje Bergstrom <tbergstrom@nvidia.com> Tested-by: Terje Bergstrom <tbergstrom@nvidia.com> Reviewed-by: Yu-Huan Hsu <yhsu@nvidia.com>
Diffstat (limited to 'drivers')
-rw-r--r--drivers/video/tegra/host/nvhost_syncpt.c9
-rw-r--r--drivers/video/tegra/host/nvhost_syncpt.h21
-rw-r--r--drivers/video/tegra/host/t20/syncpt_t20.c43
3 files changed, 46 insertions, 27 deletions
diff --git a/drivers/video/tegra/host/nvhost_syncpt.c b/drivers/video/tegra/host/nvhost_syncpt.c
index 1c63b69fb294..f5e788551a05 100644
--- a/drivers/video/tegra/host/nvhost_syncpt.c
+++ b/drivers/video/tegra/host/nvhost_syncpt.c
@@ -119,9 +119,11 @@ int nvhost_syncpt_wait_timeout(struct nvhost_syncpt *sp, u32 id,
BUG_ON(!syncpt_op(sp).update_min);
if (!nvhost_syncpt_check_max(sp, id, thresh)) {
- WARN(1, "wait %d (%s) for (%d) wouldn't be met (max %d)\n",
+ dev_warn(&syncpt_to_dev(sp)->pdev->dev,
+ "wait %d (%s) for (%d) wouldn't be met (max %d)\n",
id, syncpt_op(sp).name(sp, id), thresh,
nvhost_syncpt_read_max(sp, id));
+ nvhost_debug_dump(syncpt_to_dev(sp));
return -EINVAL;
}
@@ -185,8 +187,9 @@ int nvhost_syncpt_wait_timeout(struct nvhost_syncpt *sp, u32 id,
timeout -= check;
if (timeout) {
dev_warn(&syncpt_to_dev(sp)->pdev->dev,
- "syncpoint id %d (%s) stuck waiting %d\n",
- id, syncpt_op(sp).name(sp, id), thresh);
+ "%s: syncpoint id %d (%s) stuck waiting %d, timeout=%d\n",
+ current->comm, id, syncpt_op(sp).name(sp, id),
+ thresh, timeout);
syncpt_op(sp).debug(sp);
}
}
diff --git a/drivers/video/tegra/host/nvhost_syncpt.h b/drivers/video/tegra/host/nvhost_syncpt.h
index c8f8b4bb1262..b8d15383c510 100644
--- a/drivers/video/tegra/host/nvhost_syncpt.h
+++ b/drivers/video/tegra/host/nvhost_syncpt.h
@@ -50,17 +50,6 @@ int nvhost_syncpt_init(struct nvhost_syncpt *);
#define syncpt_to_dev(sp) container_of(sp, struct nvhost_master, syncpt)
#define syncpt_op(sp) (syncpt_to_dev(sp)->op.syncpt)
#define SYNCPT_CHECK_PERIOD 2*HZ
-static inline bool nvhost_syncpt_check_max(struct nvhost_syncpt *sp, u32 id, u32 real)
-{
- u32 max;
- if (client_managed(id))
- return true;
- smp_rmb();
- max = (u32)atomic_read(&sp->max_val[id]);
- return ((s32)(max - real) >= 0);
-}
-
-
/**
* Updates the value sent to hardware.
*/
@@ -93,6 +82,16 @@ static inline u32 nvhost_syncpt_read_min(struct nvhost_syncpt *sp, u32 id)
return (u32)atomic_read(&sp->min_val[id]);
}
+static inline bool nvhost_syncpt_check_max(struct nvhost_syncpt *sp,
+ u32 id, u32 real)
+{
+ u32 max;
+ if (client_managed(id))
+ return true;
+ max = nvhost_syncpt_read_max(sp, id);
+ return (s32)(max - real) >= 0;
+}
+
/**
* Returns true if syncpoint has reached threshold
*/
diff --git a/drivers/video/tegra/host/t20/syncpt_t20.c b/drivers/video/tegra/host/t20/syncpt_t20.c
index 781654b656da..c42877493582 100644
--- a/drivers/video/tegra/host/t20/syncpt_t20.c
+++ b/drivers/video/tegra/host/t20/syncpt_t20.c
@@ -33,9 +33,7 @@
static void t20_syncpt_reset(struct nvhost_syncpt *sp, u32 id)
{
struct nvhost_master *dev = syncpt_to_dev(sp);
- int min;
- smp_rmb();
- min = atomic_read(&sp->min_val[id]);
+ int min = nvhost_syncpt_read_min(sp, id);
writel(min, dev->sync_aperture + (HOST1X_SYNC_SYNCPT_0 + id * 4));
}
@@ -70,13 +68,18 @@ static u32 t20_syncpt_update_min(struct nvhost_syncpt *sp, u32 id)
u32 old, live;
do {
- smp_rmb();
- old = (u32)atomic_read(&sp->min_val[id]);
+ old = nvhost_syncpt_read_min(sp, id);
live = readl(sync_regs + (HOST1X_SYNC_SYNCPT_0 + id * 4));
} while ((u32)atomic_cmpxchg(&sp->min_val[id], old, live) != old);
- BUG_ON(!nvhost_syncpt_check_max(sp, id, live));
-
+ if (!nvhost_syncpt_check_max(sp, id, live)) {
+ dev_err(&syncpt_to_dev(sp)->pdev->dev,
+ "%s failed: id=%u\n",
+ __func__,
+ id);
+ nvhost_debug_dump(syncpt_to_dev(sp));
+ BUG();
+ }
return live;
}
@@ -88,7 +91,13 @@ static void t20_syncpt_cpu_incr(struct nvhost_syncpt *sp, u32 id)
{
struct nvhost_master *dev = syncpt_to_dev(sp);
BUG_ON(!nvhost_module_powered(&dev->mod));
- BUG_ON(!client_managed(id) && nvhost_syncpt_min_eq_max(sp, id));
+ if (!client_managed(id) && nvhost_syncpt_min_eq_max(sp, id)) {
+ dev_err(&syncpt_to_dev(sp)->pdev->dev,
+ "Syncpoint id %d\n",
+ id);
+ nvhost_debug_dump(syncpt_to_dev(sp));
+ BUG();
+ }
writel(BIT(id), dev->sync_aperture + HOST1X_SYNC_SYNCPT_CPU_INCR);
wmb();
}
@@ -162,12 +171,20 @@ static int t20_syncpt_wait_check(struct nvhost_syncpt *sp,
static const char *s_syncpt_names[32] = {
- "gfx_host", "", "", "", "", "", "", "", "", "", "avp_0",
- "csi_vi_0", "csi_vi_1", "vi_isp_0", "vi_isp_1", "vi_isp_2", "vi_isp_3", "vi_isp_4",
+ "gfx_host",
+ "", "", "", "", "", "", "",
+ "disp0_a", "disp1_a", "avp_0",
+ "csi_vi_0", "csi_vi_1",
+ "vi_isp_0", "vi_isp_1", "vi_isp_2", "vi_isp_3", "vi_isp_4",
"2d_0", "2d_1",
- "", "",
- "3d", "mpe", "disp0", "disp1", "vblank0", "vblank1", "mpe_ebm_eof", "mpe_wr_safe",
- "2d_tinyblt", "dsi"
+ "disp0_b", "disp1_b",
+ "3d",
+ "mpe",
+ "disp0_c", "disp1_c",
+ "vblank0", "vblank1",
+ "mpe_ebm_eof", "mpe_wr_safe",
+ "2d_tinyblt",
+ "dsi"
};
static const char *t20_syncpt_name(struct nvhost_syncpt *s, u32 id)