summaryrefslogtreecommitdiffstats
path: root/drivers/gpu/nvgpu/common/linux
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/gpu/nvgpu/common/linux')
-rw-r--r--drivers/gpu/nvgpu/common/linux/channel.c79
-rw-r--r--drivers/gpu/nvgpu/common/linux/channel.h15
-rw-r--r--drivers/gpu/nvgpu/common/linux/ioctl_channel.c21
-rw-r--r--drivers/gpu/nvgpu/common/linux/ioctl_ctrl.c21
-rw-r--r--drivers/gpu/nvgpu/common/linux/module.c16
5 files changed, 140 insertions, 12 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
43u32 nvgpu_submit_gpfifo_user_flags_to_common_flags(u32 user_flags) 45u32 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
326static 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}
347static 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
357static 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
368static 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
314int nvgpu_init_channel_support_linux(struct nvgpu_os_linux *l) 378int 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
337err_clean: 411err_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
359u32 nvgpu_get_gpfifo_entry_size(void) 438u32 nvgpu_get_gpfifo_entry_size(void)
diff --git a/drivers/gpu/nvgpu/common/linux/channel.h b/drivers/gpu/nvgpu/common/linux/channel.h
index d4cb6d55..805de55a 100644
--- a/drivers/gpu/nvgpu/common/linux/channel.h
+++ b/drivers/gpu/nvgpu/common/linux/channel.h
@@ -1,5 +1,5 @@
1/* 1/*
2 * Copyright (c) 2017, NVIDIA CORPORATION. All rights reserved. 2 * Copyright (c) 2017-2018, NVIDIA CORPORATION. All rights reserved.
3 * 3 *
4 * This program is free software; you can redistribute it and/or modify it 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, 5 * under the terms and conditions of the GNU General Public License,
@@ -29,6 +29,9 @@ struct gk20a_fence;
29struct fifo_profile_gk20a; 29struct fifo_profile_gk20a;
30struct nvgpu_os_linux; 30struct nvgpu_os_linux;
31 31
32struct sync_fence;
33struct sync_timeline;
34
32struct nvgpu_channel_completion_cb { 35struct nvgpu_channel_completion_cb {
33 /* 36 /*
34 * Signal channel owner via a callback, if set, in job cleanup with 37 * Signal channel owner via a callback, if set, in job cleanup with
@@ -52,9 +55,19 @@ struct nvgpu_error_notifier {
52 struct nvgpu_mutex mutex; 55 struct nvgpu_mutex mutex;
53}; 56};
54 57
58/*
59 * This struct contains fence_related data.
60 * e.g. sync_timeline for sync_fences.
61 */
62struct nvgpu_os_fence_framework {
63 struct sync_timeline *timeline;
64};
65
55struct nvgpu_channel_linux { 66struct nvgpu_channel_linux {
56 struct channel_gk20a *ch; 67 struct channel_gk20a *ch;
57 68
69 struct nvgpu_os_fence_framework fence_framework;
70
58 struct nvgpu_channel_completion_cb completion_cb; 71 struct nvgpu_channel_completion_cb completion_cb;
59 struct nvgpu_error_notifier error_notifier; 72 struct nvgpu_error_notifier error_notifier;
60 73
diff --git a/drivers/gpu/nvgpu/common/linux/ioctl_channel.c b/drivers/gpu/nvgpu/common/linux/ioctl_channel.c
index b4d7d501..06dfb180 100644
--- a/drivers/gpu/nvgpu/common/linux/ioctl_channel.c
+++ b/drivers/gpu/nvgpu/common/linux/ioctl_channel.c
@@ -774,6 +774,7 @@ static int gk20a_ioctl_channel_submit_gpfifo(
774 struct gk20a_fence *fence_out; 774 struct gk20a_fence *fence_out;
775 struct fifo_profile_gk20a *profile = NULL; 775 struct fifo_profile_gk20a *profile = NULL;
776 u32 submit_flags = 0; 776 u32 submit_flags = 0;
777 int fd = -1;
777 778
778 int ret = 0; 779 int ret = 0;
779 gk20a_dbg_fn(""); 780 gk20a_dbg_fn("");
@@ -794,19 +795,31 @@ static int gk20a_ioctl_channel_submit_gpfifo(
794 nvgpu_get_fence_args(&args->fence, &fence); 795 nvgpu_get_fence_args(&args->fence, &fence);
795 submit_flags = 796 submit_flags =
796 nvgpu_submit_gpfifo_user_flags_to_common_flags(args->flags); 797 nvgpu_submit_gpfifo_user_flags_to_common_flags(args->flags);
798
799 /* Try and allocate an fd here*/
800 if ((args->flags & NVGPU_SUBMIT_GPFIFO_FLAGS_FENCE_GET)
801 && (args->flags & NVGPU_SUBMIT_GPFIFO_FLAGS_SYNC_FENCE)) {
802 fd = get_unused_fd_flags(O_RDWR);
803 if (fd < 0)
804 return fd;
805 }
806
797 ret = gk20a_submit_channel_gpfifo(ch, NULL, args, args->num_entries, 807 ret = gk20a_submit_channel_gpfifo(ch, NULL, args, args->num_entries,
798 submit_flags, &fence, 808 submit_flags, &fence,
799 &fence_out, false, profile); 809 &fence_out, false, profile);
800 810
801 if (ret) 811 if (ret) {
812 if (fd != -1)
813 put_unused_fd(fd);
802 goto clean_up; 814 goto clean_up;
815 }
803 816
804 /* Convert fence_out to something we can pass back to user space. */ 817 /* Convert fence_out to something we can pass back to user space. */
805 if (args->flags & NVGPU_SUBMIT_GPFIFO_FLAGS_FENCE_GET) { 818 if (args->flags & NVGPU_SUBMIT_GPFIFO_FLAGS_FENCE_GET) {
806 if (args->flags & NVGPU_SUBMIT_GPFIFO_FLAGS_SYNC_FENCE) { 819 if (args->flags & NVGPU_SUBMIT_GPFIFO_FLAGS_SYNC_FENCE) {
807 int fd = gk20a_fence_install_fd(fence_out); 820 ret = gk20a_fence_install_fd(fence_out, fd);
808 if (fd < 0) 821 if (ret)
809 ret = fd; 822 put_unused_fd(fd);
810 else 823 else
811 args->fence.id = fd; 824 args->fence.id = fd;
812 } else { 825 } else {
diff --git a/drivers/gpu/nvgpu/common/linux/ioctl_ctrl.c b/drivers/gpu/nvgpu/common/linux/ioctl_ctrl.c
index e4b66460..70707a5c 100644
--- a/drivers/gpu/nvgpu/common/linux/ioctl_ctrl.c
+++ b/drivers/gpu/nvgpu/common/linux/ioctl_ctrl.c
@@ -344,10 +344,19 @@ static int gk20a_ctrl_prepare_compressible_read(
344 struct gk20a_fence *fence_out = NULL; 344 struct gk20a_fence *fence_out = NULL;
345 int submit_flags = nvgpu_submit_gpfifo_user_flags_to_common_flags( 345 int submit_flags = nvgpu_submit_gpfifo_user_flags_to_common_flags(
346 args->submit_flags); 346 args->submit_flags);
347 int fd = -1;
347 348
348 fence.id = args->fence.syncpt_id; 349 fence.id = args->fence.syncpt_id;
349 fence.value = args->fence.syncpt_value; 350 fence.value = args->fence.syncpt_value;
350 351
352 /* Try and allocate an fd here*/
353 if ((submit_flags & NVGPU_SUBMIT_FLAGS_FENCE_GET)
354 && (submit_flags & NVGPU_SUBMIT_FLAGS_SYNC_FENCE)) {
355 fd = get_unused_fd_flags(O_RDWR);
356 if (fd < 0)
357 return fd;
358 }
359
351 ret = gk20a_prepare_compressible_read(l, args->handle, 360 ret = gk20a_prepare_compressible_read(l, args->handle,
352 args->request_compbits, args->offset, 361 args->request_compbits, args->offset,
353 args->compbits_hoffset, args->compbits_voffset, 362 args->compbits_hoffset, args->compbits_voffset,
@@ -356,20 +365,24 @@ static int gk20a_ctrl_prepare_compressible_read(
356 submit_flags, &fence, &args->valid_compbits, 365 submit_flags, &fence, &args->valid_compbits,
357 &args->zbc_color, &fence_out); 366 &args->zbc_color, &fence_out);
358 367
359 if (ret) 368 if (ret) {
369 if (fd != -1)
370 put_unused_fd(fd);
360 return ret; 371 return ret;
372 }
361 373
362 /* Convert fence_out to something we can pass back to user space. */ 374 /* Convert fence_out to something we can pass back to user space. */
363 if (submit_flags & NVGPU_SUBMIT_FLAGS_FENCE_GET) { 375 if (submit_flags & NVGPU_SUBMIT_FLAGS_FENCE_GET) {
364 if (submit_flags & NVGPU_SUBMIT_FLAGS_SYNC_FENCE) { 376 if (submit_flags & NVGPU_SUBMIT_FLAGS_SYNC_FENCE) {
365 if (fence_out) { 377 if (fence_out) {
366 int fd = gk20a_fence_install_fd(fence_out); 378 ret = gk20a_fence_install_fd(fence_out, fd);
367 if (fd < 0) 379 if (ret)
368 ret = fd; 380 put_unused_fd(fd);
369 else 381 else
370 args->fence.fd = fd; 382 args->fence.fd = fd;
371 } else { 383 } else {
372 args->fence.fd = -1; 384 args->fence.fd = -1;
385 put_unused_fd(fd);
373 } 386 }
374 } else { 387 } else {
375 if (fence_out) { 388 if (fence_out) {
diff --git a/drivers/gpu/nvgpu/common/linux/module.c b/drivers/gpu/nvgpu/common/linux/module.c
index b9c9554b..81b3db82 100644
--- a/drivers/gpu/nvgpu/common/linux/module.c
+++ b/drivers/gpu/nvgpu/common/linux/module.c
@@ -40,6 +40,7 @@
40#include <nvgpu/enabled.h> 40#include <nvgpu/enabled.h>
41#include <nvgpu/debug.h> 41#include <nvgpu/debug.h>
42#include <nvgpu/ctxsw_trace.h> 42#include <nvgpu/ctxsw_trace.h>
43#include <nvgpu/vidmem.h>
43 44
44#include "platform_gk20a.h" 45#include "platform_gk20a.h"
45#include "sysfs.h" 46#include "sysfs.h"
@@ -252,13 +253,22 @@ int gk20a_pm_finalize_poweron(struct device *dev)
252 return err; 253 return err;
253 254
254 err = gk20a_finalize_poweron(g); 255 err = gk20a_finalize_poweron(g);
255 set_user_nice(current, nice_value); 256 if (err) {
256 if (err) 257 set_user_nice(current, nice_value);
257 goto done; 258 goto done;
259 }
258 260
259 err = nvgpu_finalize_poweron_linux(l); 261 err = nvgpu_finalize_poweron_linux(l);
260 if (err) 262 if (err) {
263 set_user_nice(current, nice_value);
261 goto done; 264 goto done;
265 }
266
267 nvgpu_init_mm_ce_context(g);
268
269 nvgpu_vidmem_thread_unpause(&g->mm);
270
271 set_user_nice(current, nice_value);
262 272
263 /* Initialise scaling: it will initialize scaling drive only once */ 273 /* Initialise scaling: it will initialize scaling drive only once */
264 if (IS_ENABLED(CONFIG_GK20A_DEVFREQ) && 274 if (IS_ENABLED(CONFIG_GK20A_DEVFREQ) &&