summaryrefslogtreecommitdiff
path: root/drivers/video/tegra/host/nvhost_syncpt.c
diff options
context:
space:
mode:
authorChris Johnson <cwj@nvidia.com>2011-04-30 14:24:44 -0700
committerNiket Sirsi <nsirsi@nvidia.com>2011-05-16 15:15:20 -0700
commit6d8d2c454e835f7cfe34371e07dac173f3153452 (patch)
treec80564468037653f45c29d607e52e8c472ae8367 /drivers/video/tegra/host/nvhost_syncpt.c
parent0edac603fc410d7b6686b27e545586b42feb7a80 (diff)
nvrm: move stale wait checking into the kerneltegra-11.2.6
The kernel now receives wait tracking data (similar to gathers and relocs) and compares the current syncpt with the threshold value. If it's old, it gets a kernel mapping and rewrites the method data to use a kernel reserved syncpt that is always 0 (so trivially pops when seen by the HW). Bug 519650 Bug 785525 Bug 803452 Note: reset the author in this commit to fix a email addr problem and since from the latest/last cherry pick there was a reworking of the code to be compatible with different user space versions it also seemed reasonable. (cherry picked from commit 4069d8e67665624ad3dceb628e572980dd57acd0) (cherry picked from commit 6e4336408588e348804a62e53386acc9abc06823) (cherry picked from commit 87a9efe751716ca741caac72b9061fdfdcec540a) Change-Id: I9c6076da2384f373d5f402bee4406b09b4ebc4ff Reviewed-on: http://git-master/r/23159 Reviewed-on: http://git-master/r/30281 Tested-by: Chris Johnson <cwj@nvidia.com> Reviewed-by: Ken Adams <kadams@nvidia.com> Reviewed-by: Prajakta Gudadhe <pgudadhe@nvidia.com>
Diffstat (limited to 'drivers/video/tegra/host/nvhost_syncpt.c')
-rw-r--r--drivers/video/tegra/host/nvhost_syncpt.c62
1 files changed, 61 insertions, 1 deletions
diff --git a/drivers/video/tegra/host/nvhost_syncpt.c b/drivers/video/tegra/host/nvhost_syncpt.c
index dd2ab0d379e0..1881716ed428 100644
--- a/drivers/video/tegra/host/nvhost_syncpt.c
+++ b/drivers/video/tegra/host/nvhost_syncpt.c
@@ -226,7 +226,7 @@ done:
}
static const char *s_syncpt_names[32] = {
- "", "", "", "", "", "", "", "", "", "", "", "",
+ "gfx_host", "", "", "", "", "", "", "", "", "", "", "",
"vi_isp_0", "vi_isp_1", "vi_isp_2", "vi_isp_3", "vi_isp_4", "vi_isp_5",
"2d_0", "2d_1",
"", "",
@@ -254,3 +254,63 @@ void nvhost_syncpt_debug(struct nvhost_syncpt *sp)
}
}
+
+/* returns true, if a <= b < c using wrapping comparison */
+static inline bool nvhost_syncpt_is_between(u32 a, u32 b, u32 c)
+{
+ return b-a < c-a;
+}
+
+/* returns true, if x >= y (mod 1 << 32) */
+static bool nvhost_syncpt_wrapping_comparison(u32 x, u32 y)
+{
+ return nvhost_syncpt_is_between(y, x, (1UL<<31UL)+y);
+}
+
+/* check for old WAITs to be removed (avoiding a wrap) */
+int nvhost_syncpt_wait_check(struct nvmap_client *nvmap,
+ struct nvhost_syncpt *sp, u32 waitchk_mask,
+ struct nvhost_waitchk *waitp, u32 waitchks)
+{
+ u32 idx;
+ int err = 0;
+
+ /* get current syncpt values */
+ for (idx = 0; idx < NV_HOST1X_SYNCPT_NB_PTS; idx++) {
+ if (BIT(idx) & waitchk_mask) {
+ nvhost_syncpt_update_min(sp, idx);
+ }
+ }
+
+ BUG_ON(!waitp);
+
+ /* compare syncpt vs wait threshold */
+ while (waitchks) {
+ u32 syncpt, override;
+
+ BUG_ON(waitp->syncpt_id > NV_HOST1X_SYNCPT_NB_PTS);
+
+ syncpt = atomic_read(&sp->min_val[waitp->syncpt_id]);
+ if (nvhost_syncpt_wrapping_comparison(syncpt, waitp->thresh)) {
+
+ /* wait has completed already, so can be removed */
+ dev_dbg(&syncpt_to_dev(sp)->pdev->dev,
+ "drop WAIT id %d (%s) thresh 0x%x, syncpt 0x%x\n",
+ waitp->syncpt_id, nvhost_syncpt_name(waitp->syncpt_id),
+ waitp->thresh, syncpt);
+
+ /* move wait to a kernel reserved syncpt (that's always 0) */
+ override = nvhost_class_host_wait_syncpt(NVSYNCPT_GRAPHICS_HOST, 0);
+
+ /* patch the wait */
+ err = nvmap_patch_wait(nvmap,
+ (struct nvmap_handle *)waitp->mem,
+ waitp->offset, override);
+ if (err)
+ break;
+ }
+ waitchks--;
+ waitp++;
+ }
+ return err;
+}