summaryrefslogtreecommitdiffstats
path: root/drivers/gpu/nvgpu/include
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/gpu/nvgpu/include')
-rw-r--r--drivers/gpu/nvgpu/include/nvgpu/semaphore.h65
1 files changed, 19 insertions, 46 deletions
diff --git a/drivers/gpu/nvgpu/include/nvgpu/semaphore.h b/drivers/gpu/nvgpu/include/nvgpu/semaphore.h
index 771cc7e1..373c5745 100644
--- a/drivers/gpu/nvgpu/include/nvgpu/semaphore.h
+++ b/drivers/gpu/nvgpu/include/nvgpu/semaphore.h
@@ -276,37 +276,18 @@ static inline bool nvgpu_semaphore_is_acquired(struct nvgpu_semaphore *s)
276} 276}
277 277
278/* 278/*
279 * If @force is set then this will not wait for the underlying semaphore to 279 * Fast-forward the hw sema to the threshold represented by sema_thresh.
280 * catch up to the passed semaphore threshold.
281 */ 280 */
282static inline void __nvgpu_semaphore_release(struct nvgpu_semaphore *s, 281static inline void nvgpu_semaphore_reset(struct nvgpu_semaphore *sema_thresh,
283 bool force,
284 struct nvgpu_semaphore_int *hw_sema) 282 struct nvgpu_semaphore_int *hw_sema)
285{ 283{
286 u32 current_val; 284 u32 current_val;
287 u32 threshold = nvgpu_semaphore_get_value(s); 285 u32 threshold = nvgpu_semaphore_get_value(sema_thresh);
288 int attempts = 0;
289 286
290 /* 287 current_val = nvgpu_semaphore_read(sema_thresh);
291 * Wait until the sema value is 1 less than the write value. That
292 * way this function is essentially an increment.
293 *
294 * TODO: tune the wait a little better.
295 */
296 while (!__nvgpu_semaphore_value_released(threshold - 1,
297 current_val = nvgpu_semaphore_read(s))) {
298 if (force)
299 break;
300 nvgpu_msleep(100);
301 attempts += 1;
302 if (attempts > 100) {
303 WARN(1, "Stall on sema release!");
304 return;
305 }
306 }
307 288
308 /* 289 /*
309 * If the semaphore has already passed the value we would write then 290 * If the semaphore has already reached the value we would write then
310 * this is really just a NO-OP. 291 * this is really just a NO-OP.
311 */ 292 */
312 if (__nvgpu_semaphore_value_released(threshold, current_val)) 293 if (__nvgpu_semaphore_value_released(threshold, current_val))
@@ -315,36 +296,28 @@ static inline void __nvgpu_semaphore_release(struct nvgpu_semaphore *s,
315 nvgpu_mem_wr(hw_sema->ch->g, &hw_sema->location.pool->rw_mem, 296 nvgpu_mem_wr(hw_sema->ch->g, &hw_sema->location.pool->rw_mem,
316 hw_sema->location.offset, threshold); 297 hw_sema->location.offset, threshold);
317 298
318 gpu_sema_verbose_dbg(hw_sema->location.pool->sema_sea->gk20a, 299 gpu_sema_verbose_dbg(hw_sema->ch->g, "(c=%d) RESET %u -> %u",
319 "(c=%d) WRITE %u", hw_sema->ch->chid, threshold); 300 hw_sema->ch->chid, current_val, threshold);
320}
321
322static inline void nvgpu_semaphore_release(struct nvgpu_semaphore *s,
323 struct nvgpu_semaphore_int *hw_sema)
324{
325 __nvgpu_semaphore_release(s, false, hw_sema);
326} 301}
327 302
328/* 303/*
329 * Configure a software based increment on this semaphore. This is useful for 304 * Update nvgpu-tracked shadow of the value in "hw_sema" and mark the threshold
330 * when we want the GPU to wait on a SW event before processing a channel. 305 * value to "s" which represents the increment that the caller must write in a
331 * Another way to describe this is when the GPU needs to wait on a SW pre-fence. 306 * pushbuf. The same nvgpu_semaphore will also represent an output fence; when
332 * The pre-fence signals SW which in turn calls nvgpu_semaphore_release() which 307 * nvgpu_semaphore_is_released(s) == true, the gpu is done with this increment.
333 * then allows the GPU to continue.
334 *
335 * Also used to prep a semaphore for an INCR by the GPU.
336 */ 308 */
337static inline void nvgpu_semaphore_incr(struct nvgpu_semaphore *s, 309static inline void nvgpu_semaphore_prepare(struct nvgpu_semaphore *s,
338 struct nvgpu_semaphore_int *hw_sema) 310 struct nvgpu_semaphore_int *hw_sema)
339{ 311{
340 BUG_ON(s->incremented); 312 int next = nvgpu_atomic_add_return(1, &hw_sema->next_value);
313
314 /* "s" should be an uninitialized sema. */
315 WARN_ON(s->incremented);
341 316
342 nvgpu_atomic_set(&s->value, nvgpu_atomic_add_return(1, &hw_sema->next_value)); 317 nvgpu_atomic_set(&s->value, next);
343 s->incremented = 1; 318 s->incremented = 1;
344 319
345 gpu_sema_verbose_dbg(s->g, 320 gpu_sema_verbose_dbg(s->g, "INCR sema for c=%d (%u)",
346 "INCR sema for c=%d (%u)", 321 hw_sema->ch->chid, next);
347 hw_sema->ch->chid,
348 nvgpu_atomic_read(&hw_sema->next_value));
349} 322}
350#endif 323#endif