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

Mikko Perttunen <[email protected]>
Newsgroups org.kernel.vger.linux-media,org.freedesktop.lists.dri-devel,org.kernel.vger.linux-kernel,org.kernel.vger.linux-tegra
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
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.