summaryrefslogtreecommitdiff
path: root/drivers/gpu/drm/msm/msm_fence.h
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/gpu/drm/msm/msm_fence.h')
-rw-r--r--drivers/gpu/drm/msm/msm_fence.h99
1 files changed, 76 insertions, 23 deletions
diff --git a/drivers/gpu/drm/msm/msm_fence.h b/drivers/gpu/drm/msm/msm_fence.h
index 56061aa1959d..148196375a0b 100644
--- a/drivers/gpu/drm/msm/msm_fence.h
+++ b/drivers/gpu/drm/msm/msm_fence.h
@@ -1,18 +1,7 @@
+/* SPDX-License-Identifier: GPL-2.0-only */
/*
* Copyright (C) 2013-2016 Red Hat
* Author: Rob Clark <robdclark@gmail.com>
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 as published by
- * the Free Software Foundation.
- *
- * This program is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
- * more details.
- *
- * You should have received a copy of the GNU General Public License along with
- * this program. If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef __MSM_FENCE_H__
@@ -20,27 +9,91 @@
#include "msm_drv.h"
+/**
+ * struct msm_fence_context - fence context for gpu
+ *
+ * Each ringbuffer has a single fence context, with the GPU writing an
+ * incrementing fence seqno at the end of each submit
+ */
struct msm_fence_context {
struct drm_device *dev;
- const char *name;
+ /** name: human readable name for fence timeline */
+ char name[32];
+ /** context: see dma_fence_context_alloc() */
unsigned context;
- /* last_fence == completed_fence --> no pending work */
- uint32_t last_fence; /* last assigned fence */
- uint32_t completed_fence; /* last completed fence */
- wait_queue_head_t event;
+ /** index: similar to context, but local to msm_fence_context's */
+ unsigned index;
+
+ /**
+ * last_fence:
+ *
+ * Last assigned fence, incremented each time a fence is created
+ * on this fence context. If last_fence == completed_fence,
+ * there is no remaining pending work
+ */
+ uint32_t last_fence;
+
+ /**
+ * completed_fence:
+ *
+ * The last completed fence, updated from the CPU after interrupt
+ * from GPU
+ */
+ uint32_t completed_fence;
+
+ /**
+ * fenceptr:
+ *
+ * The address that the GPU directly writes with completed fence
+ * seqno. This can be ahead of completed_fence. We can peek at
+ * this to see if a fence has already signaled but the CPU hasn't
+ * gotten around to handling the irq and updating completed_fence
+ */
+ volatile uint32_t *fenceptr;
+
spinlock_t spinlock;
+
+ /*
+ * TODO this doesn't really deal with multiple deadlines, like
+ * if userspace got multiple frames ahead.. OTOH atomic updates
+ * don't queue, so maybe that is ok
+ */
+
+ /** next_deadline: Time of next deadline */
+ ktime_t next_deadline;
+
+ /**
+ * next_deadline_fence:
+ *
+ * Fence value for next pending deadline. The deadline timer is
+ * canceled when this fence is signaled.
+ */
+ uint32_t next_deadline_fence;
+
+ struct hrtimer deadline_timer;
+ struct kthread_work deadline_work;
};
struct msm_fence_context * msm_fence_context_alloc(struct drm_device *dev,
- const char *name);
+ volatile uint32_t *fenceptr, const char *name);
void msm_fence_context_free(struct msm_fence_context *fctx);
-int msm_wait_fence(struct msm_fence_context *fctx, uint32_t fence,
- ktime_t *timeout, bool interruptible);
-int msm_queue_fence_cb(struct msm_fence_context *fctx,
- struct msm_fence_cb *cb, uint32_t fence);
+bool msm_fence_completed(struct msm_fence_context *fctx, uint32_t fence);
void msm_update_fence(struct msm_fence_context *fctx, uint32_t fence);
-struct dma_fence * msm_fence_alloc(struct msm_fence_context *fctx);
+struct dma_fence * msm_fence_alloc(void);
+void msm_fence_init(struct dma_fence *fence, struct msm_fence_context *fctx);
+
+static inline bool
+fence_before(uint32_t a, uint32_t b)
+{
+ return (int32_t)(a - b) < 0;
+}
+
+static inline bool
+fence_after(uint32_t a, uint32_t b)
+{
+ return (int32_t)(a - b) > 0;
+}
#endif