[PATCH 5/6] gpu: host1x: Add host1x_fence_extract()

Mikko Perttunen <[email protected]> Thu, 30 Jul 2026 13:44:45 +0900
Newsgroups org.kernel.vger.linux-tegra,org.freedesktop.lists.dri-devel,org.kernel.vger.linux-kernel,org.kernel.vger.linux-media
Message-ID <[email protected]>
Syncpoint fences are backed by a hardware syncpoint / threshold, which
various hardware is capable of waiting for directly without CPU
intervention. Add a function to allow drivers for such devices to
extract the details to allow programming the hardware accordingly.

The function also provides the host1x instance corresponding to the
syncpoint since a system may contain multiple instances of host1x with
separate sets of syncpoints.

Signed-off-by: Mikko Perttunen <[email protected]>
---
 drivers/gpu/host1x/fence.c | 43 +++++++++++++++++++++++++++++++++++++++++++
 include/linux/host1x.h     |  2 ++
 2 files changed, 45 insertions(+)

diff --git a/drivers/gpu/host1x/fence.c b/drivers/gpu/host1x/fence.c
index b9a7d0bf91f8..1acf579c562b 100644
--- a/drivers/gpu/host1x/fence.c
+++ b/drivers/gpu/host1x/fence.c
@@ -152,3 +152,46 @@ void host1x_fence_cancel(struct dma_fence *f)
 	flush_delayed_work(&sf->timeout_work);
 }
 EXPORT_SYMBOL(host1x_fence_cancel);
+
+/**
+ * host1x_fence_extract() - extract underlying syncpoint/threshold from fence
+ * @fence: fence to extract information from
+ * @host1x: out pointer for host1x instance corresponding to the syncpoint
+ * @id: out pointer for the syncpoint ID the fence pends on
+ * @threshold: out pointer for the syncpoint value the fence pends on
+ *
+ * Extracts underlying host1x hardware related information from a host1x
+ * syncpoint fence. This information can be used by devices that have direct
+ * access to host1x syncpoints to wait the fence in hardware without CPU
+ * interaction.
+ *
+ * A system might have multiple instances of host1x with separate sets of
+ * syncpoints. Callers must ensure any hardware that is programmed is accessing
+ * the correct set of syncpoints as identified by @host1x.
+ *
+ * Note that a fence that has already signalled may no longer be identifiable as
+ * a syncpoint fence, as the dma_fence framework can detach fence ops on
+ * signalled fences.
+ *
+ * Returns 0 on success, or -EINVAL if @fence is not a syncpoint fence.
+ */
+int host1x_fence_extract(struct dma_fence *fence, struct host1x **host1x,
+			 u32 *id, u32 *threshold)
+{
+	struct host1x_syncpt_fence *f;
+
+	if (rcu_access_pointer(fence->ops) != &host1x_syncpt_fence_ops)
+		return -EINVAL;
+
+	f = to_host1x_fence(fence);
+
+	if (host1x)
+		*host1x = f->sp->host;
+	if (id)
+		*id = f->sp->id;
+	if (threshold)
+		*threshold = f->threshold;
+
+	return 0;
+}
+EXPORT_SYMBOL(host1x_fence_extract);
diff --git a/include/linux/host1x.h b/include/linux/host1x.h
index a7a675783136..1221acf83942 100644
--- a/include/linux/host1x.h
+++ b/include/linux/host1x.h
@@ -237,6 +237,8 @@ void host1x_syncpt_release_vblank_reservation(struct host1x_client *client,
 struct dma_fence *host1x_fence_create(struct host1x_syncpt *sp, u32 threshold,
 				      bool timeout);
 void host1x_fence_cancel(struct dma_fence *fence);
+int host1x_fence_extract(struct dma_fence *fence, struct host1x **host1x,
+			 u32 *id, u32 *threshold);
 
 /*
  * host1x channel

-- 
2.53.0