/* check for old WAITs to be removed (avoiding a wrap) */ static int t20_syncpt_wait_check(struct nvhost_syncpt *sp, struct nvmap_client *nvmap, u32 waitchk_mask, struct nvhost_waitchk *wait, int num_waitchk) { 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(!wait && !num_waitchk); /* compare syncpt vs wait threshold */ while (num_waitchk) { u32 override; BUG_ON(wait->syncpt_id >= NV_HOST1X_SYNCPT_NB_PTS); trace_nvhost_syncpt_wait_check(wait->mem, wait->offset, wait->syncpt_id, wait->thresh); if (nvhost_syncpt_is_expired(sp, wait->syncpt_id, wait->thresh)) { /* * NULL an already satisfied WAIT_SYNCPT host method, * by patching its args in the command stream. The * method data is changed to reference a reserved * (never given out or incr) NVSYNCPT_GRAPHICS_HOST * syncpt with a matching threshold value of 0, so * is guaranteed to be popped by the host HW. */ dev_dbg(&syncpt_to_dev(sp)->dev->dev, "drop WAIT id %d (%s) thresh 0x%x, min 0x%x\n", wait->syncpt_id, syncpt_op(sp).name(sp, wait->syncpt_id), wait->thresh, nvhost_syncpt_read_min(sp, wait->syncpt_id)); /* patch the wait */ override = nvhost_class_host_wait_syncpt( NVSYNCPT_GRAPHICS_HOST, 0); err = nvmap_patch_word(nvmap, (struct nvmap_handle *)wait->mem, wait->offset, override); if (err) break; }
/* 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; }