diff options
Diffstat (limited to 'drivers/gpu/nvgpu/common/linux/channel.c')
-rw-r--r-- | drivers/gpu/nvgpu/common/linux/channel.c | 79 |
1 files changed, 79 insertions, 0 deletions
diff --git a/drivers/gpu/nvgpu/common/linux/channel.c b/drivers/gpu/nvgpu/common/linux/channel.c index a360d0df..8f2adc3a 100644 --- a/drivers/gpu/nvgpu/common/linux/channel.c +++ b/drivers/gpu/nvgpu/common/linux/channel.c | |||
@@ -40,6 +40,8 @@ | |||
40 | #include <trace/events/gk20a.h> | 40 | #include <trace/events/gk20a.h> |
41 | #include <uapi/linux/nvgpu.h> | 41 | #include <uapi/linux/nvgpu.h> |
42 | 42 | ||
43 | #include "gk20a/sync_gk20a.h" | ||
44 | |||
43 | u32 nvgpu_submit_gpfifo_user_flags_to_common_flags(u32 user_flags) | 45 | u32 nvgpu_submit_gpfifo_user_flags_to_common_flags(u32 user_flags) |
44 | { | 46 | { |
45 | u32 flags = 0; | 47 | u32 flags = 0; |
@@ -292,6 +294,10 @@ static int nvgpu_channel_alloc_linux(struct gk20a *g, struct channel_gk20a *ch) | |||
292 | ch->os_priv = priv; | 294 | ch->os_priv = priv; |
293 | priv->ch = ch; | 295 | priv->ch = ch; |
294 | 296 | ||
297 | #ifdef CONFIG_SYNC | ||
298 | ch->has_os_fence_framework_support = true; | ||
299 | #endif | ||
300 | |||
295 | err = nvgpu_mutex_init(&priv->error_notifier.mutex); | 301 | err = nvgpu_mutex_init(&priv->error_notifier.mutex); |
296 | if (err) { | 302 | if (err) { |
297 | nvgpu_kfree(g, priv); | 303 | nvgpu_kfree(g, priv); |
@@ -309,6 +315,64 @@ static void nvgpu_channel_free_linux(struct gk20a *g, struct channel_gk20a *ch) | |||
309 | 315 | ||
310 | nvgpu_mutex_destroy(&priv->error_notifier.mutex); | 316 | nvgpu_mutex_destroy(&priv->error_notifier.mutex); |
311 | nvgpu_kfree(g, priv); | 317 | nvgpu_kfree(g, priv); |
318 | |||
319 | ch->os_priv = NULL; | ||
320 | |||
321 | #ifdef CONFIG_SYNC | ||
322 | ch->has_os_fence_framework_support = false; | ||
323 | #endif | ||
324 | } | ||
325 | |||
326 | static int nvgpu_channel_init_os_fence_framework(struct channel_gk20a *ch, | ||
327 | const char *fmt, ...) | ||
328 | { | ||
329 | struct nvgpu_channel_linux *priv = ch->os_priv; | ||
330 | struct nvgpu_os_fence_framework *fence_framework; | ||
331 | char name[30]; | ||
332 | va_list args; | ||
333 | |||
334 | fence_framework = &priv->fence_framework; | ||
335 | |||
336 | va_start(args, fmt); | ||
337 | vsnprintf(name, sizeof(name), fmt, args); | ||
338 | va_end(args); | ||
339 | |||
340 | fence_framework->timeline = gk20a_sync_timeline_create(name); | ||
341 | |||
342 | if (!fence_framework->timeline) | ||
343 | return -EINVAL; | ||
344 | |||
345 | return 0; | ||
346 | } | ||
347 | static void nvgpu_channel_signal_os_fence_framework(struct channel_gk20a *ch) | ||
348 | { | ||
349 | struct nvgpu_channel_linux *priv = ch->os_priv; | ||
350 | struct nvgpu_os_fence_framework *fence_framework; | ||
351 | |||
352 | fence_framework = &priv->fence_framework; | ||
353 | |||
354 | gk20a_sync_timeline_signal(fence_framework->timeline); | ||
355 | } | ||
356 | |||
357 | static void nvgpu_channel_destroy_os_fence_framework(struct channel_gk20a *ch) | ||
358 | { | ||
359 | struct nvgpu_channel_linux *priv = ch->os_priv; | ||
360 | struct nvgpu_os_fence_framework *fence_framework; | ||
361 | |||
362 | fence_framework = &priv->fence_framework; | ||
363 | |||
364 | gk20a_sync_timeline_destroy(fence_framework->timeline); | ||
365 | fence_framework->timeline = NULL; | ||
366 | } | ||
367 | |||
368 | static bool nvgpu_channel_fence_framework_exists(struct channel_gk20a *ch) | ||
369 | { | ||
370 | struct nvgpu_channel_linux *priv = ch->os_priv; | ||
371 | struct nvgpu_os_fence_framework *fence_framework; | ||
372 | |||
373 | fence_framework = &priv->fence_framework; | ||
374 | |||
375 | return (fence_framework->timeline != NULL); | ||
312 | } | 376 | } |
313 | 377 | ||
314 | int nvgpu_init_channel_support_linux(struct nvgpu_os_linux *l) | 378 | int nvgpu_init_channel_support_linux(struct nvgpu_os_linux *l) |
@@ -332,6 +396,16 @@ int nvgpu_init_channel_support_linux(struct nvgpu_os_linux *l) | |||
332 | nvgpu_channel_work_completion_signal; | 396 | nvgpu_channel_work_completion_signal; |
333 | g->os_channel.work_completion_cancel_sync = | 397 | g->os_channel.work_completion_cancel_sync = |
334 | nvgpu_channel_work_completion_cancel_sync; | 398 | nvgpu_channel_work_completion_cancel_sync; |
399 | |||
400 | g->os_channel.os_fence_framework_inst_exists = | ||
401 | nvgpu_channel_fence_framework_exists; | ||
402 | g->os_channel.init_os_fence_framework = | ||
403 | nvgpu_channel_init_os_fence_framework; | ||
404 | g->os_channel.signal_os_fence_framework = | ||
405 | nvgpu_channel_signal_os_fence_framework; | ||
406 | g->os_channel.destroy_os_fence_framework = | ||
407 | nvgpu_channel_destroy_os_fence_framework; | ||
408 | |||
335 | return 0; | 409 | return 0; |
336 | 410 | ||
337 | err_clean: | 411 | err_clean: |
@@ -354,6 +428,11 @@ void nvgpu_remove_channel_support_linux(struct nvgpu_os_linux *l) | |||
354 | 428 | ||
355 | nvgpu_channel_free_linux(g, ch); | 429 | nvgpu_channel_free_linux(g, ch); |
356 | } | 430 | } |
431 | |||
432 | g->os_channel.os_fence_framework_inst_exists = NULL; | ||
433 | g->os_channel.init_os_fence_framework = NULL; | ||
434 | g->os_channel.signal_os_fence_framework = NULL; | ||
435 | g->os_channel.destroy_os_fence_framework = NULL; | ||
357 | } | 436 | } |
358 | 437 | ||
359 | u32 nvgpu_get_gpfifo_entry_size(void) | 438 | u32 nvgpu_get_gpfifo_entry_size(void) |