[PATCH 5/6] gpu: host1x: Add host1x_fence_extract()
From: Mikko Perttunen
Date: Thu Jul 30 2026 - 00:46:42 EST
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 <mperttunen@xxxxxxxxxx>
---
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