diff options
Diffstat (limited to 'drivers/gpu/nvgpu/os')
-rw-r--r-- | drivers/gpu/nvgpu/os/linux/ioctl_ctrl.c | 32 | ||||
-rw-r--r-- | drivers/gpu/nvgpu/os/linux/module.c | 16 | ||||
-rw-r--r-- | drivers/gpu/nvgpu/os/posix/nvgpu.c | 6 |
3 files changed, 48 insertions, 6 deletions
diff --git a/drivers/gpu/nvgpu/os/linux/ioctl_ctrl.c b/drivers/gpu/nvgpu/os/linux/ioctl_ctrl.c index 6fa15421..271c5d92 100644 --- a/drivers/gpu/nvgpu/os/linux/ioctl_ctrl.c +++ b/drivers/gpu/nvgpu/os/linux/ioctl_ctrl.c | |||
@@ -19,6 +19,7 @@ | |||
19 | #include <linux/file.h> | 19 | #include <linux/file.h> |
20 | #include <linux/anon_inodes.h> | 20 | #include <linux/anon_inodes.h> |
21 | #include <linux/fs.h> | 21 | #include <linux/fs.h> |
22 | #include <linux/pm_runtime.h> | ||
22 | #include <uapi/linux/nvgpu.h> | 23 | #include <uapi/linux/nvgpu.h> |
23 | 24 | ||
24 | #include <nvgpu/bitops.h> | 25 | #include <nvgpu/bitops.h> |
@@ -596,19 +597,46 @@ static int gk20a_ctrl_get_fbp_l2_masks( | |||
596 | static int nvgpu_gpu_ioctl_l2_fb_ops(struct gk20a *g, | 597 | static int nvgpu_gpu_ioctl_l2_fb_ops(struct gk20a *g, |
597 | struct nvgpu_gpu_l2_fb_args *args) | 598 | struct nvgpu_gpu_l2_fb_args *args) |
598 | { | 599 | { |
599 | int err = 0; | 600 | int ret; |
601 | bool always_poweron; | ||
600 | 602 | ||
601 | if ((!args->l2_flush && !args->fb_flush) || | 603 | if ((!args->l2_flush && !args->fb_flush) || |
602 | (!args->l2_flush && args->l2_invalidate)) | 604 | (!args->l2_flush && args->l2_invalidate)) |
603 | return -EINVAL; | 605 | return -EINVAL; |
604 | 606 | ||
607 | /* Handle this case for joint rails or DGPU */ | ||
608 | always_poweron = (!nvgpu_is_enabled(g, NVGPU_CAN_RAILGATE) || | ||
609 | !pm_runtime_enabled(dev_from_gk20a(g))); | ||
610 | |||
611 | /* In case of not always power_on, exit if g->power_on is false */ | ||
612 | if (!always_poweron && !gk20a_check_poweron(g)) { | ||
613 | return 0; | ||
614 | } | ||
615 | |||
616 | /* There is a small window between a call to gk20a_idle() has occured | ||
617 | * and railgate being actually triggered(setting g->power_on = false), | ||
618 | * when l2_flush can race with railgate. Its better to take a busy_lock | ||
619 | * to prevent the gk20a_idle() from proceeding. There is a very small | ||
620 | * chance that gk20a_idle() might begin before gk20a_busy(). Having | ||
621 | * a locked access to g->power_on further reduces the probability of | ||
622 | * gk20a_idle() being triggered before gk20a_busy() | ||
623 | */ | ||
624 | ret = gk20a_busy(g); | ||
625 | |||
626 | if (ret != 0) { | ||
627 | nvgpu_err(g, "failed to take power ref"); | ||
628 | return ret; | ||
629 | } | ||
630 | |||
605 | if (args->l2_flush) | 631 | if (args->l2_flush) |
606 | g->ops.mm.l2_flush(g, args->l2_invalidate ? true : false); | 632 | g->ops.mm.l2_flush(g, args->l2_invalidate ? true : false); |
607 | 633 | ||
608 | if (args->fb_flush) | 634 | if (args->fb_flush) |
609 | g->ops.mm.fb_flush(g); | 635 | g->ops.mm.fb_flush(g); |
610 | 636 | ||
611 | return err; | 637 | gk20a_idle(g); |
638 | |||
639 | return 0; | ||
612 | } | 640 | } |
613 | 641 | ||
614 | static int nvgpu_gpu_ioctl_set_mmu_debug_mode( | 642 | static int nvgpu_gpu_ioctl_set_mmu_debug_mode( |
diff --git a/drivers/gpu/nvgpu/os/linux/module.c b/drivers/gpu/nvgpu/os/linux/module.c index 18345ada..5627abfd 100644 --- a/drivers/gpu/nvgpu/os/linux/module.c +++ b/drivers/gpu/nvgpu/os/linux/module.c | |||
@@ -107,10 +107,7 @@ struct device_node *nvgpu_get_node(struct gk20a *g) | |||
107 | 107 | ||
108 | void gk20a_busy_noresume(struct gk20a *g) | 108 | void gk20a_busy_noresume(struct gk20a *g) |
109 | { | 109 | { |
110 | int ret = pm_runtime_get_if_in_use(dev_from_gk20a(g)); | 110 | pm_runtime_get_noresume(dev_from_gk20a(g)); |
111 | |||
112 | if (ret <= 0) | ||
113 | pm_runtime_get_noresume(dev_from_gk20a(g)); | ||
114 | } | 111 | } |
115 | 112 | ||
116 | /* | 113 | /* |
@@ -262,6 +259,17 @@ int nvgpu_finalize_poweron_linux(struct nvgpu_os_linux *l) | |||
262 | return 0; | 259 | return 0; |
263 | } | 260 | } |
264 | 261 | ||
262 | bool gk20a_check_poweron(struct gk20a *g) | ||
263 | { | ||
264 | bool ret; | ||
265 | |||
266 | nvgpu_mutex_acquire(&g->power_lock); | ||
267 | ret = g->power_on; | ||
268 | nvgpu_mutex_release(&g->power_lock); | ||
269 | |||
270 | return ret; | ||
271 | } | ||
272 | |||
265 | int gk20a_pm_finalize_poweron(struct device *dev) | 273 | int gk20a_pm_finalize_poweron(struct device *dev) |
266 | { | 274 | { |
267 | struct gk20a *g = get_gk20a(dev); | 275 | struct gk20a *g = get_gk20a(dev); |
diff --git a/drivers/gpu/nvgpu/os/posix/nvgpu.c b/drivers/gpu/nvgpu/os/posix/nvgpu.c index 2f84dc6e..e485ed73 100644 --- a/drivers/gpu/nvgpu/os/posix/nvgpu.c +++ b/drivers/gpu/nvgpu/os/posix/nvgpu.c | |||
@@ -24,6 +24,7 @@ | |||
24 | #include <stdlib.h> | 24 | #include <stdlib.h> |
25 | #include <pthread.h> | 25 | #include <pthread.h> |
26 | 26 | ||
27 | #include <nvgpu/gk20a.h> | ||
27 | #include <nvgpu/bug.h> | 28 | #include <nvgpu/bug.h> |
28 | #include <nvgpu/types.h> | 29 | #include <nvgpu/types.h> |
29 | #include <nvgpu/atomic.h> | 30 | #include <nvgpu/atomic.h> |
@@ -92,6 +93,11 @@ void gk20a_idle_nosuspend(struct gk20a *g) | |||
92 | { | 93 | { |
93 | } | 94 | } |
94 | 95 | ||
96 | bool gk20a_check_poweron(struct gk20a *g) | ||
97 | { | ||
98 | return false; | ||
99 | } | ||
100 | |||
95 | int gk20a_busy(struct gk20a *g) | 101 | int gk20a_busy(struct gk20a *g) |
96 | { | 102 | { |
97 | nvgpu_atomic_inc(&g->usage_count); | 103 | nvgpu_atomic_inc(&g->usage_count); |