diff options
Diffstat (limited to 'drivers/gpu')
-rw-r--r-- | drivers/gpu/nvgpu/include/nvgpu/vgpu/tegra_vgpu.h | 2 | ||||
-rw-r--r-- | drivers/gpu/nvgpu/os/linux/module.c | 34 | ||||
-rw-r--r-- | drivers/gpu/nvgpu/os/linux/platform_gk20a.h | 3 | ||||
-rw-r--r-- | drivers/gpu/nvgpu/os/linux/vgpu/gv11b/platform_gv11b_vgpu_tegra.c | 5 | ||||
-rw-r--r-- | drivers/gpu/nvgpu/os/linux/vgpu/platform_vgpu_tegra.c | 7 | ||||
-rw-r--r-- | drivers/gpu/nvgpu/os/linux/vgpu/vgpu_linux.c | 36 | ||||
-rw-r--r-- | drivers/gpu/nvgpu/os/linux/vgpu/vgpu_linux.h | 11 |
7 files changed, 90 insertions, 8 deletions
diff --git a/drivers/gpu/nvgpu/include/nvgpu/vgpu/tegra_vgpu.h b/drivers/gpu/nvgpu/include/nvgpu/vgpu/tegra_vgpu.h index 3e4372eb..6d05e44c 100644 --- a/drivers/gpu/nvgpu/include/nvgpu/vgpu/tegra_vgpu.h +++ b/drivers/gpu/nvgpu/include/nvgpu/vgpu/tegra_vgpu.h | |||
@@ -118,6 +118,8 @@ enum { | |||
118 | TEGRA_VGPU_CMD_MAP_SYNCPT = 79, | 118 | TEGRA_VGPU_CMD_MAP_SYNCPT = 79, |
119 | TEGRA_VGPU_CMD_TSG_BIND_CHANNEL_EX = 80, | 119 | TEGRA_VGPU_CMD_TSG_BIND_CHANNEL_EX = 80, |
120 | TEGRA_VGPU_CMD_UPDATE_PC_SAMPLING = 81, | 120 | TEGRA_VGPU_CMD_UPDATE_PC_SAMPLING = 81, |
121 | TEGRA_VGPU_CMD_SUSPEND = 82, | ||
122 | TEGRA_VGPU_CMD_RESUME = 83, | ||
121 | }; | 123 | }; |
122 | 124 | ||
123 | struct tegra_vgpu_connect_params { | 125 | struct tegra_vgpu_connect_params { |
diff --git a/drivers/gpu/nvgpu/os/linux/module.c b/drivers/gpu/nvgpu/os/linux/module.c index af71cc81..4516490b 100644 --- a/drivers/gpu/nvgpu/os/linux/module.c +++ b/drivers/gpu/nvgpu/os/linux/module.c | |||
@@ -967,9 +967,15 @@ static int gk20a_pm_suspend(struct device *dev) | |||
967 | int idle_usage_count = 0; | 967 | int idle_usage_count = 0; |
968 | 968 | ||
969 | if (!g->power_on) { | 969 | if (!g->power_on) { |
970 | if (platform->suspend) | ||
971 | ret = platform->suspend(dev); | ||
972 | if (ret) | ||
973 | return ret; | ||
974 | |||
970 | if (!pm_runtime_enabled(dev)) | 975 | if (!pm_runtime_enabled(dev)) |
971 | gk20a_pm_railgate(dev); | 976 | ret = gk20a_pm_railgate(dev); |
972 | return 0; | 977 | |
978 | return ret; | ||
973 | } | 979 | } |
974 | 980 | ||
975 | if (nvgpu_atomic_read(&g->usage_count) > idle_usage_count) | 981 | if (nvgpu_atomic_read(&g->usage_count) > idle_usage_count) |
@@ -980,25 +986,41 @@ static int gk20a_pm_suspend(struct device *dev) | |||
980 | return ret; | 986 | return ret; |
981 | 987 | ||
982 | if (platform->suspend) | 988 | if (platform->suspend) |
983 | platform->suspend(dev); | 989 | ret = platform->suspend(dev); |
990 | if (ret) | ||
991 | return ret; | ||
984 | 992 | ||
985 | g->suspended = true; | 993 | g->suspended = true; |
986 | 994 | ||
987 | return 0; | 995 | return ret; |
988 | } | 996 | } |
989 | 997 | ||
990 | static int gk20a_pm_resume(struct device *dev) | 998 | static int gk20a_pm_resume(struct device *dev) |
991 | { | 999 | { |
1000 | struct gk20a_platform *platform = dev_get_drvdata(dev); | ||
992 | struct gk20a *g = get_gk20a(dev); | 1001 | struct gk20a *g = get_gk20a(dev); |
993 | int ret = 0; | 1002 | int ret = 0; |
994 | 1003 | ||
995 | if (!g->suspended) { | 1004 | if (!g->suspended) { |
1005 | if (platform->resume) | ||
1006 | ret = platform->resume(dev); | ||
1007 | if (ret) | ||
1008 | return ret; | ||
1009 | |||
996 | if (!pm_runtime_enabled(dev)) | 1010 | if (!pm_runtime_enabled(dev)) |
997 | gk20a_pm_unrailgate(dev); | 1011 | ret = gk20a_pm_unrailgate(dev); |
998 | return 0; | 1012 | |
1013 | return ret; | ||
999 | } | 1014 | } |
1000 | 1015 | ||
1016 | if (platform->resume) | ||
1017 | ret = platform->resume(dev); | ||
1018 | if (ret) | ||
1019 | return ret; | ||
1020 | |||
1001 | ret = gk20a_pm_runtime_resume(dev); | 1021 | ret = gk20a_pm_runtime_resume(dev); |
1022 | if (ret) | ||
1023 | return ret; | ||
1002 | 1024 | ||
1003 | g->suspended = false; | 1025 | g->suspended = false; |
1004 | 1026 | ||
diff --git a/drivers/gpu/nvgpu/os/linux/platform_gk20a.h b/drivers/gpu/nvgpu/os/linux/platform_gk20a.h index 9a99b7fe..d9725e4c 100644 --- a/drivers/gpu/nvgpu/os/linux/platform_gk20a.h +++ b/drivers/gpu/nvgpu/os/linux/platform_gk20a.h | |||
@@ -158,6 +158,9 @@ struct gk20a_platform { | |||
158 | /* Device is going to be suspended */ | 158 | /* Device is going to be suspended */ |
159 | int (*suspend)(struct device *); | 159 | int (*suspend)(struct device *); |
160 | 160 | ||
161 | /* Device is going to be resumed */ | ||
162 | int (*resume)(struct device *); | ||
163 | |||
161 | /* Called to turn off the device */ | 164 | /* Called to turn off the device */ |
162 | int (*railgate)(struct device *dev); | 165 | int (*railgate)(struct device *dev); |
163 | 166 | ||
diff --git a/drivers/gpu/nvgpu/os/linux/vgpu/gv11b/platform_gv11b_vgpu_tegra.c b/drivers/gpu/nvgpu/os/linux/vgpu/gv11b/platform_gv11b_vgpu_tegra.c index 66911626..8eada9df 100644 --- a/drivers/gpu/nvgpu/os/linux/vgpu/gv11b/platform_gv11b_vgpu_tegra.c +++ b/drivers/gpu/nvgpu/os/linux/vgpu/gv11b/platform_gv11b_vgpu_tegra.c | |||
@@ -22,6 +22,7 @@ | |||
22 | #include "os/linux/vgpu/clk_vgpu.h" | 22 | #include "os/linux/vgpu/clk_vgpu.h" |
23 | #include "os/linux/platform_gk20a.h" | 23 | #include "os/linux/platform_gk20a.h" |
24 | #include "os/linux/os_linux.h" | 24 | #include "os/linux/os_linux.h" |
25 | #include "os/linux/vgpu/vgpu_linux.h" | ||
25 | 26 | ||
26 | static int gv11b_vgpu_probe(struct device *dev) | 27 | static int gv11b_vgpu_probe(struct device *dev) |
27 | { | 28 | { |
@@ -94,4 +95,8 @@ struct gk20a_platform gv11b_vgpu_tegra_platform = { | |||
94 | .devfreq_governor = "userspace", | 95 | .devfreq_governor = "userspace", |
95 | 96 | ||
96 | .virtual_dev = true, | 97 | .virtual_dev = true, |
98 | |||
99 | /* power management callbacks */ | ||
100 | .suspend = vgpu_tegra_suspend, | ||
101 | .resume = vgpu_tegra_resume, | ||
97 | }; | 102 | }; |
diff --git a/drivers/gpu/nvgpu/os/linux/vgpu/platform_vgpu_tegra.c b/drivers/gpu/nvgpu/os/linux/vgpu/platform_vgpu_tegra.c index e4819e7d..44879a45 100644 --- a/drivers/gpu/nvgpu/os/linux/vgpu/platform_vgpu_tegra.c +++ b/drivers/gpu/nvgpu/os/linux/vgpu/platform_vgpu_tegra.c | |||
@@ -1,7 +1,7 @@ | |||
1 | /* | 1 | /* |
2 | * Tegra Virtualized GPU Platform Interface | 2 | * Tegra Virtualized GPU Platform Interface |
3 | * | 3 | * |
4 | * Copyright (c) 2014-2017, NVIDIA CORPORATION. All rights reserved. | 4 | * Copyright (c) 2014-2018, NVIDIA CORPORATION. All rights reserved. |
5 | * | 5 | * |
6 | * This program is free software; you can redistribute it and/or modify it | 6 | * This program is free software; you can redistribute it and/or modify it |
7 | * under the terms and conditions of the GNU General Public License, | 7 | * under the terms and conditions of the GNU General Public License, |
@@ -21,6 +21,7 @@ | |||
21 | #include "gk20a/gk20a.h" | 21 | #include "gk20a/gk20a.h" |
22 | #include "os/linux/platform_gk20a.h" | 22 | #include "os/linux/platform_gk20a.h" |
23 | #include "clk_vgpu.h" | 23 | #include "clk_vgpu.h" |
24 | #include "vgpu_linux.h" | ||
24 | 25 | ||
25 | static int gk20a_tegra_probe(struct device *dev) | 26 | static int gk20a_tegra_probe(struct device *dev) |
26 | { | 27 | { |
@@ -66,4 +67,8 @@ struct gk20a_platform vgpu_tegra_platform = { | |||
66 | .devfreq_governor = "userspace", | 67 | .devfreq_governor = "userspace", |
67 | 68 | ||
68 | .virtual_dev = true, | 69 | .virtual_dev = true, |
70 | |||
71 | /* power management callbacks */ | ||
72 | .suspend = vgpu_tegra_suspend, | ||
73 | .resume = vgpu_tegra_resume, | ||
69 | }; | 74 | }; |
diff --git a/drivers/gpu/nvgpu/os/linux/vgpu/vgpu_linux.c b/drivers/gpu/nvgpu/os/linux/vgpu/vgpu_linux.c index a7612e54..25024e7d 100644 --- a/drivers/gpu/nvgpu/os/linux/vgpu/vgpu_linux.c +++ b/drivers/gpu/nvgpu/os/linux/vgpu/vgpu_linux.c | |||
@@ -147,7 +147,9 @@ int vgpu_pm_prepare_poweroff(struct device *dev) | |||
147 | if (!g->power_on) | 147 | if (!g->power_on) |
148 | return 0; | 148 | return 0; |
149 | 149 | ||
150 | ret = gk20a_channel_suspend(g); | 150 | if (g->ops.fifo.channel_suspend) |
151 | ret = g->ops.fifo.channel_suspend(g); | ||
152 | |||
151 | if (ret) | 153 | if (ret) |
152 | return ret; | 154 | return ret; |
153 | 155 | ||
@@ -473,3 +475,35 @@ bool vgpu_is_reduced_bar1(struct gk20a *g) | |||
473 | 475 | ||
474 | return resource_size(l->bar1_mem) == (resource_size_t)f->userd.size; | 476 | return resource_size(l->bar1_mem) == (resource_size_t)f->userd.size; |
475 | } | 477 | } |
478 | |||
479 | int vgpu_tegra_suspend(struct device *dev) | ||
480 | { | ||
481 | struct tegra_vgpu_cmd_msg msg = {}; | ||
482 | struct gk20a *g = get_gk20a(dev); | ||
483 | int err = 0; | ||
484 | |||
485 | msg.cmd = TEGRA_VGPU_CMD_SUSPEND; | ||
486 | msg.handle = vgpu_get_handle(g); | ||
487 | err = vgpu_comm_sendrecv(&msg, sizeof(msg), sizeof(msg)); | ||
488 | err = err ? err : msg.ret; | ||
489 | if (err) | ||
490 | nvgpu_err(g, "vGPU suspend failed\n"); | ||
491 | |||
492 | return err; | ||
493 | } | ||
494 | |||
495 | int vgpu_tegra_resume(struct device *dev) | ||
496 | { | ||
497 | struct tegra_vgpu_cmd_msg msg = {}; | ||
498 | struct gk20a *g = get_gk20a(dev); | ||
499 | int err = 0; | ||
500 | |||
501 | msg.cmd = TEGRA_VGPU_CMD_RESUME; | ||
502 | msg.handle = vgpu_get_handle(g); | ||
503 | err = vgpu_comm_sendrecv(&msg, sizeof(msg), sizeof(msg)); | ||
504 | err = err ? err : msg.ret; | ||
505 | if (err) | ||
506 | nvgpu_err(g, "vGPU resume failed\n"); | ||
507 | |||
508 | return err; | ||
509 | } | ||
diff --git a/drivers/gpu/nvgpu/os/linux/vgpu/vgpu_linux.h b/drivers/gpu/nvgpu/os/linux/vgpu/vgpu_linux.h index 38379cf2..ff7d3a66 100644 --- a/drivers/gpu/nvgpu/os/linux/vgpu/vgpu_linux.h +++ b/drivers/gpu/nvgpu/os/linux/vgpu/vgpu_linux.h | |||
@@ -33,6 +33,9 @@ int vgpu_remove(struct platform_device *dev); | |||
33 | 33 | ||
34 | void vgpu_create_sysfs(struct device *dev); | 34 | void vgpu_create_sysfs(struct device *dev); |
35 | void vgpu_remove_sysfs(struct device *dev); | 35 | void vgpu_remove_sysfs(struct device *dev); |
36 | |||
37 | int vgpu_tegra_suspend(struct device *dev); | ||
38 | int vgpu_tegra_resume(struct device *dev); | ||
36 | #else | 39 | #else |
37 | /* define placeholders for functions used outside of vgpu */ | 40 | /* define placeholders for functions used outside of vgpu */ |
38 | 41 | ||
@@ -52,6 +55,14 @@ static inline int vgpu_remove(struct platform_device *dev) | |||
52 | { | 55 | { |
53 | return -ENOSYS; | 56 | return -ENOSYS; |
54 | } | 57 | } |
58 | static inline int vgpu_tegra_suspend(struct device *dev) | ||
59 | { | ||
60 | return -ENOSYS; | ||
61 | } | ||
62 | static inline int vgpu_tegra_resume(struct device *dev) | ||
63 | { | ||
64 | return -ENOSYS; | ||
65 | } | ||
55 | #endif | 66 | #endif |
56 | 67 | ||
57 | #endif | 68 | #endif |