diff options
Diffstat (limited to 'drivers/gpu/nvgpu/include')
-rw-r--r-- | drivers/gpu/nvgpu/include/nvgpu/semaphore.h | 62 |
1 files changed, 32 insertions, 30 deletions
diff --git a/drivers/gpu/nvgpu/include/nvgpu/semaphore.h b/drivers/gpu/nvgpu/include/nvgpu/semaphore.h index 9c74d300..e66b2188 100644 --- a/drivers/gpu/nvgpu/include/nvgpu/semaphore.h +++ b/drivers/gpu/nvgpu/include/nvgpu/semaphore.h | |||
@@ -50,15 +50,18 @@ | |||
50 | 50 | ||
51 | struct nvgpu_semaphore_sea; | 51 | struct nvgpu_semaphore_sea; |
52 | 52 | ||
53 | struct nvgpu_semaphore_loc { | ||
54 | struct nvgpu_semaphore_pool *pool; /* Pool that owns this sema. */ | ||
55 | u32 offset; /* Byte offset into the pool. */ | ||
56 | }; | ||
57 | |||
53 | /* | 58 | /* |
54 | * Underlying semaphore data structure. This semaphore can be shared amongst | 59 | * Underlying semaphore data structure. This semaphore can be shared amongst |
55 | * other semaphore instances. | 60 | * other semaphore instances. |
56 | */ | 61 | */ |
57 | struct nvgpu_semaphore_int { | 62 | struct nvgpu_semaphore_int { |
58 | int idx; /* Semaphore index. */ | 63 | struct nvgpu_semaphore_loc location; |
59 | u32 offset; /* Offset into the pool. */ | ||
60 | nvgpu_atomic_t next_value; /* Next available value. */ | 64 | nvgpu_atomic_t next_value; /* Next available value. */ |
61 | struct nvgpu_semaphore_pool *p; /* Pool that owns this sema. */ | ||
62 | struct channel_gk20a *ch; /* Channel that owns this sema. */ | 65 | struct channel_gk20a *ch; /* Channel that owns this sema. */ |
63 | }; | 66 | }; |
64 | 67 | ||
@@ -68,7 +71,8 @@ struct nvgpu_semaphore_int { | |||
68 | * semaphore to be shared among an essentially infinite number of submits. | 71 | * semaphore to be shared among an essentially infinite number of submits. |
69 | */ | 72 | */ |
70 | struct nvgpu_semaphore { | 73 | struct nvgpu_semaphore { |
71 | struct nvgpu_semaphore_int *hw_sema; | 74 | struct gk20a *g; |
75 | struct nvgpu_semaphore_loc location; | ||
72 | 76 | ||
73 | nvgpu_atomic_t value; | 77 | nvgpu_atomic_t value; |
74 | int incremented; | 78 | int incremented; |
@@ -195,8 +199,8 @@ void nvgpu_semaphore_free_hw_sema(struct channel_gk20a *ch); | |||
195 | */ | 199 | */ |
196 | static inline u64 nvgpu_semaphore_gpu_rw_va(struct nvgpu_semaphore *s) | 200 | static inline u64 nvgpu_semaphore_gpu_rw_va(struct nvgpu_semaphore *s) |
197 | { | 201 | { |
198 | return __nvgpu_semaphore_pool_gpu_va(s->hw_sema->p, false) + | 202 | return __nvgpu_semaphore_pool_gpu_va(s->location.pool, false) + |
199 | s->hw_sema->offset; | 203 | s->location.offset; |
200 | } | 204 | } |
201 | 205 | ||
202 | /* | 206 | /* |
@@ -205,20 +209,20 @@ static inline u64 nvgpu_semaphore_gpu_rw_va(struct nvgpu_semaphore *s) | |||
205 | */ | 209 | */ |
206 | static inline u64 nvgpu_semaphore_gpu_ro_va(struct nvgpu_semaphore *s) | 210 | static inline u64 nvgpu_semaphore_gpu_ro_va(struct nvgpu_semaphore *s) |
207 | { | 211 | { |
208 | return __nvgpu_semaphore_pool_gpu_va(s->hw_sema->p, true) + | 212 | return __nvgpu_semaphore_pool_gpu_va(s->location.pool, true) + |
209 | s->hw_sema->offset; | 213 | s->location.offset; |
210 | } | 214 | } |
211 | 215 | ||
212 | static inline u64 nvgpu_hw_sema_addr(struct nvgpu_semaphore_int *hw_sema) | 216 | static inline u64 nvgpu_hw_sema_addr(struct nvgpu_semaphore_int *hw_sema) |
213 | { | 217 | { |
214 | return __nvgpu_semaphore_pool_gpu_va(hw_sema->p, true) + | 218 | return __nvgpu_semaphore_pool_gpu_va(hw_sema->location.pool, true) + |
215 | hw_sema->offset; | 219 | hw_sema->location.offset; |
216 | } | 220 | } |
217 | 221 | ||
218 | static inline u32 __nvgpu_semaphore_read(struct nvgpu_semaphore_int *hw_sema) | 222 | static inline u32 __nvgpu_semaphore_read(struct nvgpu_semaphore_int *hw_sema) |
219 | { | 223 | { |
220 | return nvgpu_mem_rd(hw_sema->ch->g, | 224 | return nvgpu_mem_rd(hw_sema->ch->g, &hw_sema->location.pool->rw_mem, |
221 | &hw_sema->p->rw_mem, hw_sema->offset); | 225 | hw_sema->location.offset); |
222 | } | 226 | } |
223 | 227 | ||
224 | /* | 228 | /* |
@@ -226,7 +230,8 @@ static inline u32 __nvgpu_semaphore_read(struct nvgpu_semaphore_int *hw_sema) | |||
226 | */ | 230 | */ |
227 | static inline u32 nvgpu_semaphore_read(struct nvgpu_semaphore *s) | 231 | static inline u32 nvgpu_semaphore_read(struct nvgpu_semaphore *s) |
228 | { | 232 | { |
229 | return __nvgpu_semaphore_read(s->hw_sema); | 233 | return nvgpu_mem_rd(s->g, &s->location.pool->rw_mem, |
234 | s->location.offset); | ||
230 | } | 235 | } |
231 | 236 | ||
232 | /* | 237 | /* |
@@ -270,19 +275,14 @@ static inline bool nvgpu_semaphore_is_acquired(struct nvgpu_semaphore *s) | |||
270 | return !nvgpu_semaphore_is_released(s); | 275 | return !nvgpu_semaphore_is_released(s); |
271 | } | 276 | } |
272 | 277 | ||
273 | static inline u32 nvgpu_semaphore_next_value(struct nvgpu_semaphore *s) | ||
274 | { | ||
275 | return (u32)nvgpu_atomic_read(&s->hw_sema->next_value); | ||
276 | } | ||
277 | |||
278 | /* | 278 | /* |
279 | * If @force is set then this will not wait for the underlying semaphore to | 279 | * If @force is set then this will not wait for the underlying semaphore to |
280 | * catch up to the passed semaphore threshold. | 280 | * catch up to the passed semaphore threshold. |
281 | */ | 281 | */ |
282 | static inline void __nvgpu_semaphore_release(struct nvgpu_semaphore *s, | 282 | static inline void __nvgpu_semaphore_release(struct nvgpu_semaphore *s, |
283 | bool force) | 283 | bool force, |
284 | struct nvgpu_semaphore_int *hw_sema) | ||
284 | { | 285 | { |
285 | struct nvgpu_semaphore_int *hw_sema = s->hw_sema; | ||
286 | u32 current_val; | 286 | u32 current_val; |
287 | u32 threshold = nvgpu_semaphore_get_value(s); | 287 | u32 threshold = nvgpu_semaphore_get_value(s); |
288 | int attempts = 0; | 288 | int attempts = 0; |
@@ -312,16 +312,17 @@ static inline void __nvgpu_semaphore_release(struct nvgpu_semaphore *s, | |||
312 | if (__nvgpu_semaphore_value_released(threshold, current_val)) | 312 | if (__nvgpu_semaphore_value_released(threshold, current_val)) |
313 | return; | 313 | return; |
314 | 314 | ||
315 | nvgpu_mem_wr(hw_sema->ch->g, &hw_sema->p->rw_mem, hw_sema->offset, | 315 | nvgpu_mem_wr(hw_sema->ch->g, &hw_sema->location.pool->rw_mem, |
316 | threshold); | 316 | hw_sema->location.offset, threshold); |
317 | 317 | ||
318 | gpu_sema_verbose_dbg(hw_sema->p->sema_sea->gk20a, | 318 | gpu_sema_verbose_dbg(hw_sema->location.pool->sema_sea->gk20a, |
319 | "(c=%d) WRITE %u", hw_sema->ch->chid, threshold); | 319 | "(c=%d) WRITE %u", hw_sema->ch->chid, threshold); |
320 | } | 320 | } |
321 | 321 | ||
322 | static inline void nvgpu_semaphore_release(struct nvgpu_semaphore *s) | 322 | static inline void nvgpu_semaphore_release(struct nvgpu_semaphore *s, |
323 | struct nvgpu_semaphore_int *hw_sema) | ||
323 | { | 324 | { |
324 | __nvgpu_semaphore_release(s, false); | 325 | __nvgpu_semaphore_release(s, false, hw_sema); |
325 | } | 326 | } |
326 | 327 | ||
327 | /* | 328 | /* |
@@ -333,16 +334,17 @@ static inline void nvgpu_semaphore_release(struct nvgpu_semaphore *s) | |||
333 | * | 334 | * |
334 | * Also used to prep a semaphore for an INCR by the GPU. | 335 | * Also used to prep a semaphore for an INCR by the GPU. |
335 | */ | 336 | */ |
336 | static inline void nvgpu_semaphore_incr(struct nvgpu_semaphore *s) | 337 | static inline void nvgpu_semaphore_incr(struct nvgpu_semaphore *s, |
338 | struct nvgpu_semaphore_int *hw_sema) | ||
337 | { | 339 | { |
338 | BUG_ON(s->incremented); | 340 | BUG_ON(s->incremented); |
339 | 341 | ||
340 | nvgpu_atomic_set(&s->value, nvgpu_atomic_add_return(1, &s->hw_sema->next_value)); | 342 | nvgpu_atomic_set(&s->value, nvgpu_atomic_add_return(1, &hw_sema->next_value)); |
341 | s->incremented = 1; | 343 | s->incremented = 1; |
342 | 344 | ||
343 | gpu_sema_verbose_dbg(s->hw_sema->p->sema_sea->gk20a, | 345 | gpu_sema_verbose_dbg(s->g, |
344 | "INCR sema for c=%d (%u)", | 346 | "INCR sema for c=%d (%u)", |
345 | s->hw_sema->ch->chid, | 347 | hw_sema->ch->chid, |
346 | nvgpu_semaphore_next_value(s)); | 348 | nvgpu_atomic_read(&hw_sema->next_value)); |
347 | } | 349 | } |
348 | #endif | 350 | #endif |