aboutsummaryrefslogtreecommitdiffstats
path: root/include/os/linux/linux-channel.c
diff options
context:
space:
mode:
authorJoshua Bakita <bakitajoshua@gmail.com>2023-06-28 18:24:25 -0400
committerJoshua Bakita <bakitajoshua@gmail.com>2023-06-28 18:24:25 -0400
commit01e6fac4d61fdd7fff5433942ec93fc2ea1e4df1 (patch)
tree4ef34501728a087be24f4ba0af90f91486bf780b /include/os/linux/linux-channel.c
parent306a03d18b305e4e573be3b2931978fa10679eb9 (diff)
Include nvgpu headers
These are needed to build on NVIDIA's Jetson boards for the time being. Only a couple structs are required, so it should be fairly easy to remove this dependency at some point in the future.
Diffstat (limited to 'include/os/linux/linux-channel.c')
-rw-r--r--include/os/linux/linux-channel.c657
1 files changed, 657 insertions, 0 deletions
diff --git a/include/os/linux/linux-channel.c b/include/os/linux/linux-channel.c
new file mode 100644
index 0000000..d035baf
--- /dev/null
+++ b/include/os/linux/linux-channel.c
@@ -0,0 +1,657 @@
1/*
2 * Copyright (c) 2017-2018, NVIDIA Corporation. All rights reserved.
3 *
4 * This program is free software; you can redistribute it and/or modify it
5 * under the terms and conditions of the GNU General Public License,
6 * version 2, as published by the Free Software Foundation.
7 *
8 * This program is distributed in the hope it will be useful, but WITHOUT
9 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
10 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
11 * more details.
12 *
13 * You should have received a copy of the GNU General Public License
14 * along with this program. If not, see <http://www.gnu.org/licenses/>.
15 */
16
17#include <nvgpu/enabled.h>
18#include <nvgpu/debug.h>
19#include <nvgpu/error_notifier.h>
20#include <nvgpu/os_sched.h>
21#include <nvgpu/gk20a.h>
22#include <nvgpu/channel.h>
23#include <nvgpu/dma.h>
24
25/*
26 * This is required for nvgpu_vm_find_buf() which is used in the tracing
27 * code. Once we can get and access userspace buffers without requiring
28 * direct dma_buf usage this can be removed.
29 */
30#include <nvgpu/linux/vm.h>
31
32#include "channel.h"
33#include "ioctl_channel.h"
34#include "os_linux.h"
35#include "dmabuf.h"
36
37#include <nvgpu/hw/gk20a/hw_pbdma_gk20a.h>
38
39#include <linux/uaccess.h>
40#include <linux/dma-buf.h>
41#include <trace/events/gk20a.h>
42#include <uapi/linux/nvgpu.h>
43
44#include "sync_sema_android.h"
45
46u32 nvgpu_submit_gpfifo_user_flags_to_common_flags(u32 user_flags)
47{
48 u32 flags = 0;
49
50 if (user_flags & NVGPU_SUBMIT_GPFIFO_FLAGS_FENCE_WAIT)
51 flags |= NVGPU_SUBMIT_FLAGS_FENCE_WAIT;
52
53 if (user_flags & NVGPU_SUBMIT_GPFIFO_FLAGS_FENCE_GET)
54 flags |= NVGPU_SUBMIT_FLAGS_FENCE_GET;
55
56 if (user_flags & NVGPU_SUBMIT_GPFIFO_FLAGS_HW_FORMAT)
57 flags |= NVGPU_SUBMIT_FLAGS_HW_FORMAT;
58
59 if (user_flags & NVGPU_SUBMIT_GPFIFO_FLAGS_SYNC_FENCE)
60 flags |= NVGPU_SUBMIT_FLAGS_SYNC_FENCE;
61
62 if (user_flags & NVGPU_SUBMIT_GPFIFO_FLAGS_SUPPRESS_WFI)
63 flags |= NVGPU_SUBMIT_FLAGS_SUPPRESS_WFI;
64
65 if (user_flags & NVGPU_SUBMIT_GPFIFO_FLAGS_SKIP_BUFFER_REFCOUNTING)
66 flags |= NVGPU_SUBMIT_FLAGS_SKIP_BUFFER_REFCOUNTING;
67
68 return flags;
69}
70
71/*
72 * API to convert error_notifiers in common code and of the form
73 * NVGPU_ERR_NOTIFIER_* into Linux specific error_notifiers exposed to user
74 * space and of the form NVGPU_CHANNEL_*
75 */
76static u32 nvgpu_error_notifier_to_channel_notifier(u32 error_notifier)
77{
78 switch (error_notifier) {
79 case NVGPU_ERR_NOTIFIER_FIFO_ERROR_IDLE_TIMEOUT:
80 return NVGPU_CHANNEL_FIFO_ERROR_IDLE_TIMEOUT;
81 case NVGPU_ERR_NOTIFIER_GR_ERROR_SW_METHOD:
82 return NVGPU_CHANNEL_GR_ERROR_SW_METHOD;
83 case NVGPU_ERR_NOTIFIER_GR_ERROR_SW_NOTIFY:
84 return NVGPU_CHANNEL_GR_ERROR_SW_NOTIFY;
85 case NVGPU_ERR_NOTIFIER_GR_EXCEPTION:
86 return NVGPU_CHANNEL_GR_EXCEPTION;
87 case NVGPU_ERR_NOTIFIER_GR_SEMAPHORE_TIMEOUT:
88 return NVGPU_CHANNEL_GR_SEMAPHORE_TIMEOUT;
89 case NVGPU_ERR_NOTIFIER_GR_ILLEGAL_NOTIFY:
90 return NVGPU_CHANNEL_GR_ILLEGAL_NOTIFY;
91 case NVGPU_ERR_NOTIFIER_FIFO_ERROR_MMU_ERR_FLT:
92 return NVGPU_CHANNEL_FIFO_ERROR_MMU_ERR_FLT;
93 case NVGPU_ERR_NOTIFIER_PBDMA_ERROR:
94 return NVGPU_CHANNEL_PBDMA_ERROR;
95 case NVGPU_ERR_NOTIFIER_FECS_ERR_UNIMP_FIRMWARE_METHOD:
96 return NVGPU_CHANNEL_FECS_ERR_UNIMP_FIRMWARE_METHOD;
97 case NVGPU_ERR_NOTIFIER_RESETCHANNEL_VERIF_ERROR:
98 return NVGPU_CHANNEL_RESETCHANNEL_VERIF_ERROR;
99 case NVGPU_ERR_NOTIFIER_PBDMA_PUSHBUFFER_CRC_MISMATCH:
100 return NVGPU_CHANNEL_PBDMA_PUSHBUFFER_CRC_MISMATCH;
101 }
102
103 pr_warn("%s: invalid error_notifier requested %u\n", __func__, error_notifier);
104
105 return error_notifier;
106}
107
108/**
109 * nvgpu_set_error_notifier_locked()
110 * Should be called with ch->error_notifier_mutex held
111 *
112 * error should be of the form NVGPU_ERR_NOTIFIER_*
113 */
114void nvgpu_set_error_notifier_locked(struct channel_gk20a *ch, u32 error)
115{
116 struct nvgpu_channel_linux *priv = ch->os_priv;
117
118 error = nvgpu_error_notifier_to_channel_notifier(error);
119
120 if (priv->error_notifier.dmabuf) {
121 struct nvgpu_notification *notification =
122 priv->error_notifier.notification;
123 struct timespec time_data;
124 u64 nsec;
125
126 getnstimeofday(&time_data);
127 nsec = ((u64)time_data.tv_sec) * 1000000000u +
128 (u64)time_data.tv_nsec;
129 notification->time_stamp.nanoseconds[0] =
130 (u32)nsec;
131 notification->time_stamp.nanoseconds[1] =
132 (u32)(nsec >> 32);
133 notification->info32 = error;
134 notification->status = 0xffff;
135
136 nvgpu_err(ch->g,
137 "error notifier set to %d for ch %d", error, ch->chid);
138 }
139}
140
141/* error should be of the form NVGPU_ERR_NOTIFIER_* */
142void nvgpu_set_error_notifier(struct channel_gk20a *ch, u32 error)
143{
144 struct nvgpu_channel_linux *priv = ch->os_priv;
145
146 nvgpu_mutex_acquire(&priv->error_notifier.mutex);
147 nvgpu_set_error_notifier_locked(ch, error);
148 nvgpu_mutex_release(&priv->error_notifier.mutex);
149}
150
151void nvgpu_set_error_notifier_if_empty(struct channel_gk20a *ch, u32 error)
152{
153 struct nvgpu_channel_linux *priv = ch->os_priv;
154
155 nvgpu_mutex_acquire(&priv->error_notifier.mutex);
156 if (priv->error_notifier.dmabuf) {
157 struct nvgpu_notification *notification =
158 priv->error_notifier.notification;
159
160 /* Don't overwrite error flag if it is already set */
161 if (notification->status != 0xffff)
162 nvgpu_set_error_notifier_locked(ch, error);
163 }
164 nvgpu_mutex_release(&priv->error_notifier.mutex);
165}
166
167/* error_notifier should be of the form NVGPU_ERR_NOTIFIER_* */
168bool nvgpu_is_error_notifier_set(struct channel_gk20a *ch, u32 error_notifier)
169{
170 struct nvgpu_channel_linux *priv = ch->os_priv;
171 bool notifier_set = false;
172
173 error_notifier = nvgpu_error_notifier_to_channel_notifier(error_notifier);
174
175 nvgpu_mutex_acquire(&priv->error_notifier.mutex);
176 if (priv->error_notifier.dmabuf) {
177 struct nvgpu_notification *notification =
178 priv->error_notifier.notification;
179 u32 err = notification->info32;
180
181 if (err == error_notifier)
182 notifier_set = true;
183 }
184 nvgpu_mutex_release(&priv->error_notifier.mutex);
185
186 return notifier_set;
187}
188
189static void gk20a_channel_update_runcb_fn(struct work_struct *work)
190{
191 struct nvgpu_channel_completion_cb *completion_cb =
192 container_of(work, struct nvgpu_channel_completion_cb, work);
193 struct nvgpu_channel_linux *priv =
194 container_of(completion_cb,
195 struct nvgpu_channel_linux, completion_cb);
196 struct channel_gk20a *ch = priv->ch;
197 void (*fn)(struct channel_gk20a *, void *);
198 void *user_data;
199
200 nvgpu_spinlock_acquire(&completion_cb->lock);
201 fn = completion_cb->fn;
202 user_data = completion_cb->user_data;
203 nvgpu_spinlock_release(&completion_cb->lock);
204
205 if (fn)
206 fn(ch, user_data);
207}
208
209static void nvgpu_channel_work_c