summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorDebarshi Dutta <ddutta@nvidia.com>2020-04-14 06:58:53 -0400
committermobile promotions <svcmobile_promotions@nvidia.com>2020-04-16 12:55:31 -0400
commit9d1e07ca184869eb0082b418d0d1cf6e62af3a40 (patch)
treeb1a0f0ce6a872dfc9622ff3d65f967154890e509
parent06942bd268fca1bbe37f11710cfc655708291ecc (diff)
gpu: nvgpu: change system suspend's implementation
Currently, for platforms with canRailgate device characteristics disabled, suspend can block as deterministic channels hold busy references. This patch makes the change to first hold off any new jobs for deterministic channels and then reverts back the busy references taken by those channels. Following this, suspend also waits for the device to get idle by waiting (with timeout) for the nvgpu's internal usage counter to be come zero. This ensures there are no further jobs in progress and allows the system to go into a suspend state. Bug 200598228 Bug 2930266 Change-Id: Id02b4d41a9c2dd64303b2e2449dbed48c12aea4c Signed-off-by: Debarshi Dutta <ddutta@nvidia.com> Reviewed-on: https://git-master.nvidia.com/r/c/linux-nvgpu/+/2328489 Reviewed-by: automaticguardword <automaticguardword@nvidia.com> Reviewed-by: Automatic_Commit_Validation_User Reviewed-by: Konsta Holtta <kholtta@nvidia.com> Reviewed-by: Shashank Singh <shashsingh@nvidia.com> Reviewed-by: Sami Kiminki <skiminki@nvidia.com> Reviewed-by: Alex Waterman <alexw@nvidia.com> Reviewed-by: Bibek Basu <bbasu@nvidia.com> Reviewed-by: mobile promotions <svcmobile_promotions@nvidia.com> Tested-by: mobile promotions <svcmobile_promotions@nvidia.com> GVS: Gerrit_Virtual_Submit
-rw-r--r--drivers/gpu/nvgpu/os/linux/module.c39
1 files changed, 33 insertions, 6 deletions
diff --git a/drivers/gpu/nvgpu/os/linux/module.c b/drivers/gpu/nvgpu/os/linux/module.c
index 5627abfd..807df2ca 100644
--- a/drivers/gpu/nvgpu/os/linux/module.c
+++ b/drivers/gpu/nvgpu/os/linux/module.c
@@ -1,7 +1,7 @@
1/* 1/*
2 * GK20A Graphics 2 * GK20A Graphics
3 * 3 *
4 * Copyright (c) 2011-2018, NVIDIA CORPORATION. All rights reserved. 4 * Copyright (c) 2011-2020, 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,
@@ -1058,11 +1058,13 @@ static int gk20a_pm_suspend(struct device *dev)
1058 struct gk20a_platform *platform = dev_get_drvdata(dev); 1058 struct gk20a_platform *platform = dev_get_drvdata(dev);
1059 struct gk20a *g = get_gk20a(dev); 1059 struct gk20a *g = get_gk20a(dev);
1060 int ret = 0; 1060 int ret = 0;
1061 int idle_usage_count = 0; 1061 int usage_count;
1062 struct nvgpu_timeout timeout;
1062 1063
1063 if (!g->power_on) { 1064 if (!g->power_on) {
1064 if (platform->suspend) 1065 if (platform->suspend)
1065 ret = platform->suspend(dev); 1066 ret = platform->suspend(dev);
1067
1066 if (ret) 1068 if (ret)
1067 return ret; 1069 return ret;
1068 1070
@@ -1072,20 +1074,43 @@ static int gk20a_pm_suspend(struct device *dev)
1072 return ret; 1074 return ret;
1073 } 1075 }
1074 1076
1075 if (nvgpu_atomic_read(&g->usage_count) > idle_usage_count) 1077 nvgpu_timeout_init(g, &timeout, GK20A_WAIT_FOR_IDLE_MS,
1076 return -EBUSY; 1078 NVGPU_TIMER_CPU_TIMER);
1079 /*
1080 * Hold back deterministic submits and changes to deterministic
1081 * channels - this must be outside the power busy locks.
1082 */
1083 gk20a_channel_deterministic_idle(g);
1084
1085 /* check and wait until GPU is idle (with a timeout) */
1086 do {
1087 nvgpu_usleep_range(1000, 1100);
1088 usage_count = nvgpu_atomic_read(&g->usage_count);
1089 } while (usage_count != 0 && !nvgpu_timeout_expired(&timeout));
1090
1091 if (usage_count != 0) {
1092 nvgpu_err(g, "failed to idle - usage_count %d", usage_count);
1093 ret = -EINVAL;
1094 goto fail_idle;
1095 }
1077 1096
1078 ret = gk20a_pm_runtime_suspend(dev); 1097 ret = gk20a_pm_runtime_suspend(dev);
1079 if (ret) 1098 if (ret)
1080 return ret; 1099 goto fail_idle;
1081 1100
1082 if (platform->suspend) 1101 if (platform->suspend)
1083 ret = platform->suspend(dev); 1102 ret = platform->suspend(dev);
1084 if (ret) 1103 if (ret)
1085 return ret; 1104 goto fail_suspend;
1086 1105
1087 g->suspended = true; 1106 g->suspended = true;
1088 1107
1108 return 0;
1109
1110fail_suspend:
1111 gk20a_pm_runtime_resume(dev);
1112fail_idle:
1113 gk20a_channel_deterministic_unidle(g);
1089 return ret; 1114 return ret;
1090} 1115}
1091 1116
@@ -1118,6 +1143,8 @@ static int gk20a_pm_resume(struct device *dev)
1118 1143
1119 g->suspended = false; 1144 g->suspended = false;
1120 1145
1146 gk20a_channel_deterministic_unidle(g);
1147
1121 return ret; 1148 return ret;
1122} 1149}
1123 1150