summaryrefslogtreecommitdiffstats
path: root/drivers
diff options
context:
space:
mode:
authorDeepak Bhosale <dbhosale@nvidia.com>2018-05-30 16:12:24 -0400
committermobile promotions <svcmobile_promotions@nvidia.com>2018-06-21 16:56:50 -0400
commite4e2c1882865163ad53eeaf96acf83802ffbec71 (patch)
treee433b02a198e6c943397da13c792ba75d0c285a2 /drivers
parent90fc8d653fba60a6f7b96e7d91ff02361a3a4890 (diff)
gpu: nvgpu: suspend/resume support for vGPU
- Added suspend/resume power management callbacks for vGPU - Added suspend/resume commands for communication between vGPU and RM server - Added suspend/resume message parameters for IVC messages between vGPU and RM server JIRA EVLR-2305 JIRA EVLR-2306 Change-Id: I83a314b4e125a53117d16c5ea72dbc5d8ef96ef7 Signed-off-by: Deepak Bhosale <dbhosale@nvidia.com> Reviewed-on: https://git-master.nvidia.com/r/1735153 Reviewed-by: Automatic_Commit_Validation_User Reviewed-by: Richard Zhao <rizhao@nvidia.com> Reviewed-by: svc-mobile-coverity <svc-mobile-coverity@nvidia.com> Reviewed-by: Terje Bergstrom <tbergstrom@nvidia.com> GVS: Gerrit_Virtual_Submit Reviewed-by: Nirav Patel <nipatel@nvidia.com> Reviewed-by: mobile promotions <svcmobile_promotions@nvidia.com> Tested-by: mobile promotions <svcmobile_promotions@nvidia.com>
Diffstat (limited to 'drivers')
-rw-r--r--drivers/gpu/nvgpu/include/nvgpu/vgpu/tegra_vgpu.h2
-rw-r--r--drivers/gpu/nvgpu/os/linux/module.c34
-rw-r--r--drivers/gpu/nvgpu/os/linux/platform_gk20a.h3
-rw-r--r--drivers/gpu/nvgpu/os/linux/vgpu/gv11b/platform_gv11b_vgpu_tegra.c5
-rw-r--r--drivers/gpu/nvgpu/os/linux/vgpu/platform_vgpu_tegra.c7
-rw-r--r--drivers/gpu/nvgpu/os/linux/vgpu/vgpu_linux.c36
-rw-r--r--drivers/gpu/nvgpu/os/linux/vgpu/vgpu_linux.h11
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
123struct tegra_vgpu_connect_params { 125struct 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
990static int gk20a_pm_resume(struct device *dev) 998static 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
26static int gv11b_vgpu_probe(struct device *dev) 27static 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
25static int gk20a_tegra_probe(struct device *dev) 26static 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
479int 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
495int 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
34void vgpu_create_sysfs(struct device *dev); 34void vgpu_create_sysfs(struct device *dev);
35void vgpu_remove_sysfs(struct device *dev); 35void vgpu_remove_sysfs(struct device *dev);
36
37int vgpu_tegra_suspend(struct device *dev);
38int 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}
58static inline int vgpu_tegra_suspend(struct device *dev)
59{
60 return -ENOSYS;
61}
62static inline int vgpu_tegra_resume(struct device *dev)
63{
64 return -ENOSYS;
65}
55#endif 66#endif
56 67
57#endif 68#endif