summaryrefslogtreecommitdiffstats
path: root/drivers/gpu/nvgpu/common/linux/timers.c
diff options
context:
space:
mode:
authorTerje Bergstrom <tbergstrom@nvidia.com>2018-04-18 15:59:00 -0400
committermobile promotions <svcmobile_promotions@nvidia.com>2018-06-15 20:47:31 -0400
commit2a2c16af5f9f1ccfc93a13e820d5381e5c881e92 (patch)
tree2e5d7b042270a649978e5bb540857012c85fb5b5 /drivers/gpu/nvgpu/common/linux/timers.c
parent98d996f4ffb0137d119b5849cae46d7b7e5693e1 (diff)
gpu: nvgpu: Move Linux files away from common
Move all Linux source code files to drivers/gpu/nvgpu/os/linux from drivers/gpu/nvgpu/common/linux. This changes the meaning of common to be OS independent. JIRA NVGPU-598 JIRA NVGPU-601 Change-Id: Ib7f2a43d3688bb0d0b7dcc48469a6783fd988ce9 Signed-off-by: Terje Bergstrom <tbergstrom@nvidia.com> Reviewed-on: https://git-master.nvidia.com/r/1747714 Reviewed-by: mobile promotions <svcmobile_promotions@nvidia.com> Tested-by: mobile promotions <svcmobile_promotions@nvidia.com>
Diffstat (limited to 'drivers/gpu/nvgpu/common/linux/timers.c')
-rw-r--r--drivers/gpu/nvgpu/common/linux/timers.c270
1 files changed, 0 insertions, 270 deletions
diff --git a/drivers/gpu/nvgpu/common/linux/timers.c b/drivers/gpu/nvgpu/common/linux/timers.c
deleted file mode 100644
index d1aa641f..00000000
--- a/drivers/gpu/nvgpu/common/linux/timers.c
+++ /dev/null
@@ -1,270 +0,0 @@
1/*
2 * Copyright (c) 2016-2017, 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 <linux/ktime.h>
18#include <linux/delay.h>
19
20#include <nvgpu/timers.h>
21#include <nvgpu/soc.h>
22
23#include "gk20a/gk20a.h"
24
25#include "platform_gk20a.h"
26
27/*
28 * Returns 1 if the platform is pre-Si and should ignore the timeout checking.
29 * Setting %NVGPU_TIMER_NO_PRE_SI will make this always return 0 (i.e do the
30 * timeout check regardless of platform).
31 */
32static int nvgpu_timeout_is_pre_silicon(struct nvgpu_timeout *timeout)
33{
34 if (timeout->flags & NVGPU_TIMER_NO_PRE_SI)
35 return 0;
36
37 return !nvgpu_platform_is_silicon(timeout->g);
38}
39
40/**
41 * nvgpu_timeout_init - Init timer.
42 *
43 * @g - nvgpu device.
44 * @timeout - The timer.
45 * @duration - Timeout in milliseconds or number of retries.
46 * @flags - Flags for timer.
47 *
48 * This configures the timeout to start the timeout duration now, i.e: when this
49 * function is called. Available flags to pass to @flags:
50 *
51 * %NVGPU_TIMER_CPU_TIMER
52 * %NVGPU_TIMER_RETRY_TIMER
53 * %NVGPU_TIMER_NO_PRE_SI
54 * %NVGPU_TIMER_SILENT_TIMEOUT
55 *
56 * If neither %NVGPU_TIMER_CPU_TIMER or %NVGPU_TIMER_RETRY_TIMER is passed then
57 * a CPU timer is used by default.
58 */
59int nvgpu_timeout_init(struct gk20a *g, struct nvgpu_timeout *timeout,
60 u32 duration, unsigned long flags)
61{
62 if (flags & ~NVGPU_TIMER_FLAG_MASK)
63 return -EINVAL;
64
65 memset(timeout, 0, sizeof(*timeout));
66
67 timeout->g = g;
68 timeout->flags = flags;
69
70 if (flags & NVGPU_TIMER_RETRY_TIMER)
71 timeout->retries.max = duration;
72 else
73 timeout->time = ktime_to_ns(ktime_add_ns(ktime_get(),
74 (s64)NSEC_PER_MSEC * duration));
75
76 return 0;
77}
78
79static int __nvgpu_timeout_expired_msg_cpu(struct nvgpu_timeout *timeout,
80 void *caller,
81 const char *fmt, va_list args)
82{
83 struct gk20a *g = timeout->g;
84 ktime_t now = ktime_get();
85
86 if (nvgpu_timeout_is_pre_silicon(timeout))
87 return 0;
88
89 if (ktime_after(now, ns_to_ktime(timeout->time))) {
90 if (!(timeout->flags & NVGPU_TIMER_SILENT_TIMEOUT)) {
91 char buf[128];
92
93 vsnprintf(buf, sizeof(buf), fmt, args);
94
95 nvgpu_err(g, "Timeout detected @ %pF %s", caller, buf);
96 }
97
98 return -ETIMEDOUT;
99 }
100
101 return 0;
102}
103
104static int __nvgpu_timeout_expired_msg_retry(struct nvgpu_timeout *timeout,
105 void *caller,
106 const char *fmt, va_list args)
107{
108 struct gk20a *g = timeout->g;
109
110 if (nvgpu_timeout_is_pre_silicon(timeout))
111 return 0;
112
113 if (timeout->retries.attempted >= timeout->retries.max) {
114 if (!(timeout->flags & NVGPU_TIMER_SILENT_TIMEOUT)) {
115 char buf[128];
116
117 vsnprintf(buf, sizeof(buf), fmt, args);
118
119 nvgpu_err(g, "No more retries @ %pF %s", caller, buf);
120 }
121
122 return -ETIMEDOUT;
123 }
124
125 timeout->retries.attempted++;
126
127 return 0;
128}
129
130/**
131 * __nvgpu_timeout_expired_msg - Check if a timeout has expired.
132 *
133 * @timeout - The timeout to check.
134 * @caller - Address of the caller of this function.
135 * @fmt - The fmt string.
136 *
137 * Returns -ETIMEDOUT if the timeout has expired, 0 otherwise.
138 *
139 * If a timeout occurs and %NVGPU_TIMER_SILENT_TIMEOUT is not set in the timeout
140 * then a message is printed based on %fmt.
141 */
142int __nvgpu_timeout_expired_msg(struct nvgpu_timeout *timeout,
143 void *caller, const char *fmt, ...)
144{
145 int ret;
146 va_list args;
147
148 va_start(args, fmt);
149 if (timeout->flags & NVGPU_TIMER_RETRY_TIMER)
150 ret = __nvgpu_timeout_expired_msg_retry(timeout, caller, fmt,
151 args);
152 else
153 ret = __nvgpu_timeout_expired_msg_cpu(timeout, caller, fmt,
154 args);
155 va_end(args);
156
157 return ret;
158}
159
160/**
161 * nvgpu_timeout_peek_expired - Check the status of a timeout.
162 *
163 * @timeout - The timeout to check.
164 *
165 * Returns non-zero if the timeout is expired, zero otherwise. In the case of
166 * retry timers this will not increment the underlying retry count. Also if the
167 * timer has expired no messages will be printed.
168 *
169 * This function honors the pre-Si check as well.
170 */
171int nvgpu_timeout_peek_expired(struct nvgpu_timeout *timeout)
172{
173 if (nvgpu_timeout_is_pre_silicon(timeout))
174 return 0;
175
176 if (timeout->flags & NVGPU_TIMER_RETRY_TIMER)
177 return timeout->retries.attempted >= timeout->retries.max;
178 else
179 return ktime_after(ktime_get(), ns_to_ktime(timeout->time));
180}
181
182/**
183 * nvgpu_udelay - Delay for some number of microseconds.
184 *
185 * @usecs - Microseconds to wait for.
186 *
187 * Wait for at least @usecs microseconds. This is not guaranteed to be perfectly
188 * accurate. This is normally backed by a busy-loop so this means waits should
189 * be kept short, below 100us. If longer delays are necessary then
190 * nvgpu_msleep() should be preferred.
191 *
192 * Alternatively, on some platforms, nvgpu_usleep_range() is usable. This
193 * function will attempt to not use a busy-loop.
194 */
195void nvgpu_udelay(unsigned int usecs)
196{
197 udelay(usecs);
198}
199
200/**
201 * nvgpu_usleep_range - Sleep for a range of microseconds.
202 *
203 * @min_us - Minimum wait time.
204 * @max_us - Maximum wait time.
205 *
206 * Wait for some number of microseconds between @min_us and @max_us. This,
207 * unlike nvgpu_udelay(), will attempt to sleep for the passed number of
208 * microseconds instead of busy looping. Not all platforms support this,
209 * and in that case this reduces to nvgpu_udelay(min_us).
210 *
211 * Linux note: this is not safe to use in atomic context. If you are in
212 * atomic context you must use nvgpu_udelay().
213 */
214void nvgpu_usleep_range(unsigned int min_us, unsigned int max_us)
215{
216 usleep_range(min_us, max_us);
217}
218
219/**
220 * nvgpu_msleep - Sleep for some milliseconds.
221 *
222 * @msecs - Sleep for at least this many milliseconds.
223 *
224 * Sleep for at least @msecs of milliseconds. For small @msecs (less than 20 ms
225 * or so) the sleep will be significantly longer due to scheduling overhead and
226 * mechanics.
227 */
228void nvgpu_msleep(unsigned int msecs)
229{
230 msleep(msecs);
231}
232
233/**
234 * nvgpu_current_time_ms - Time in milliseconds from a monotonic clock.
235 *
236 * Return a clock in millisecond units. The start time of the clock is
237 * unspecified; the time returned can be compared with older ones to measure
238 * durations. The source clock does not jump when the system clock is adjusted.
239 */
240s64 nvgpu_current_time_ms(void)
241{
242 return ktime_to_ms(ktime_get());
243}
244
245/**
246 * nvgpu_current_time_ns - Time in nanoseconds from a monotonic clock.
247 *
248 * Return a clock in nanosecond units. The start time of the clock is
249 * unspecified; the time returned can be compared with older ones to measure
250 * durations. The source clock does not jump when the system clock is adjusted.
251 */
252s64 nvgpu_current_time_ns(void)
253{
254 return ktime_to_ns(ktime_get());
255}
256
257/**
258 * nvgpu_hr_timestamp - Opaque 'high resolution' time stamp.
259 *
260 * Return a "high resolution" time stamp. It does not really matter exactly what
261 * it is, so long as it generally returns unique values and monotonically
262 * increases - wrap around _is_ possible though in a system running for long
263 * enough.
264 *
265 * Note: what high resolution means is system dependent.
266 */
267u64 nvgpu_hr_timestamp(void)
268{
269 return get_cycles();
270}