Ejemplo n.º 1
0
/* 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;
		}
Ejemplo n.º 2
0
/* 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;
		}