summaryrefslogtreecommitdiffstats
path: root/drivers/gpu/nvgpu/include/nvgpu/semaphore.h
diff options
context:
space:
mode:
authorKonsta Holtta <kholtta@nvidia.com>2018-03-27 03:27:06 -0400
committermobile promotions <svcmobile_promotions@nvidia.com>2018-03-27 13:13:26 -0400
commit9b70ad24934988141c585d9fd85c59f5c9d58a38 (patch)
tree07c61f0c3062008c6f92fc0659c49f7ea3a568d0 /drivers/gpu/nvgpu/include/nvgpu/semaphore.h
parent27908cf4a980cb56daa530641cf1817d4e3f9faa (diff)
gpu: nvgpu: delete semaphore release support
Semaphores don't need to be released from CPU anymore, so clarify the code by deleting nvgpu_semaphore_release() and refactoring __nvgpu_semaphore_release() to nvgpu_semaphore_reset() that only "fast-forwards" the semaphore to a later value. While doing this, the meaning of nvgpu_semaphore_incr() changes, so rename it to nvgpu_semaphore_prepare(). Now it's only used to prepare an nvgpu_semaphore for a value that the HW will increment the sema to. Also change the BUG_ON that guards sema double-inits into just WARN_ON. Change-Id: I6f6df368ec5436cc97a229697742b6a4115dca51 Signed-off-by: Konsta Holtta <kholtta@nvidia.com> Reviewed-on: https://git-master.nvidia.com/r/1680361 Reviewed-by: svc-mobile-coverity <svc-mobile-coverity@nvidia.com> GVS: Gerrit_Virtual_Submit Reviewed-by: Automatic_Commit_Validation_User Reviewed-by: Alex Waterman <alexw@nvidia.com> Reviewed-by: Terje Bergstrom <tbergstrom@nvidia.com> Reviewed-by: mobile promotions <svcmobile_promotions@nvidia.com> Tested-by: mobile promotions <svcmobile_promotions@nvidia.com>
Diffstat (limited to 'drivers/gpu/nvgpu/include/nvgpu/semaphore.h')
-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