diff options
author | seshendra Gadagottu <sgadagottu@nvidia.com> | 2018-03-20 15:28:04 -0400 |
---|---|---|
committer | Tejal Kudav <tkudav@nvidia.com> | 2018-06-14 09:44:06 -0400 |
commit | 40cefb666f3767059383052346d4c0faa9195a48 (patch) | |
tree | 36c848f78eabae4117ca2c7acc01da6f9479dd3c /drivers/gpu/nvgpu/common/linux | |
parent | 054546525571dde1117376176f00511f13168f07 (diff) |
gpu: nvgpu: gpu railgate handling with runtime pm
Earlier implementation of railgate disable config is disabling
runtime pm during pm_init. This is causing multiple issues:
1. gpu rail will be on as soon as nvgpu driver probe is called.
Actual gpu hw init may happen at much later point of time.
2. This is breaking railgate_enable sysfs node functionality.
railgate_enable is not working if runtime pm is disabled.
To avoid all these issues for railgate disable, enable runtime pm
during pm_init and set auto-suspend delay to negative (-1), which
will disable runtime pm suspend calls.
Also fixed following issues along with this:
1. Updated railgate_enable debugfs implementation to use auto-suspend delay.
To disable railgating:
Set auto-suspend delay with negative value(-1) which will disable runtime
pm suspend.
To enable railgating:
Set auto-suspend delay with railgate_delay value.
Also removed redundant user_railgate_disabled gk20a device data and
replaced with can_railgate, where ever it is applicable.
2. Initialized default railgate_delay to 500msec to avoid railgate
on/off transitions with railigate enable from disabled state.
3. Created railgate_residency debug fs node irrespective of can_railgate
initial state. This is helping with the case, where initial state of
railgate state off and then railgate enable is done through sysfs node.
Bug 2073029
Change-Id: I531da6d93ba8907e806f65a1de2a447c1ec2665c
Signed-off-by: seshendra Gadagottu <sgadagottu@nvidia.com>
Reviewed-on: https://git-master.nvidia.com/r/1694944
Reviewed-by: mobile promotions <svcmobile_promotions@nvidia.com>
Tested-by: mobile promotions <svcmobile_promotions@nvidia.com>
Diffstat (limited to 'drivers/gpu/nvgpu/common/linux')
-rw-r--r-- | drivers/gpu/nvgpu/common/linux/debug.c | 3 | ||||
-rw-r--r-- | drivers/gpu/nvgpu/common/linux/driver_common.c | 6 | ||||
-rw-r--r-- | drivers/gpu/nvgpu/common/linux/module.c | 32 | ||||
-rw-r--r-- | drivers/gpu/nvgpu/common/linux/sysfs.c | 17 |
4 files changed, 27 insertions, 31 deletions
diff --git a/drivers/gpu/nvgpu/common/linux/debug.c b/drivers/gpu/nvgpu/common/linux/debug.c index ee93a901..8738f3e7 100644 --- a/drivers/gpu/nvgpu/common/linux/debug.c +++ b/drivers/gpu/nvgpu/common/linux/debug.c | |||
@@ -267,9 +267,6 @@ static int gk20a_railgating_debugfs_init(struct gk20a *g) | |||
267 | struct nvgpu_os_linux *l = nvgpu_os_linux_from_gk20a(g); | 267 | struct nvgpu_os_linux *l = nvgpu_os_linux_from_gk20a(g); |
268 | struct dentry *d; | 268 | struct dentry *d; |
269 | 269 | ||
270 | if (!g->can_railgate) | ||
271 | return 0; | ||
272 | |||
273 | d = debugfs_create_file( | 270 | d = debugfs_create_file( |
274 | "railgate_residency", S_IRUGO|S_IWUSR, l->debugfs, g, | 271 | "railgate_residency", S_IRUGO|S_IWUSR, l->debugfs, g, |
275 | &railgate_residency_fops); | 272 | &railgate_residency_fops); |
diff --git a/drivers/gpu/nvgpu/common/linux/driver_common.c b/drivers/gpu/nvgpu/common/linux/driver_common.c index 015046dd..2475912a 100644 --- a/drivers/gpu/nvgpu/common/linux/driver_common.c +++ b/drivers/gpu/nvgpu/common/linux/driver_common.c | |||
@@ -168,8 +168,12 @@ static void nvgpu_init_pm_vars(struct gk20a *g) | |||
168 | g->ptimer_src_freq = platform->ptimer_src_freq; | 168 | g->ptimer_src_freq = platform->ptimer_src_freq; |
169 | g->support_pmu = support_gk20a_pmu(dev_from_gk20a(g)); | 169 | g->support_pmu = support_gk20a_pmu(dev_from_gk20a(g)); |
170 | g->can_railgate = platform->can_railgate_init; | 170 | g->can_railgate = platform->can_railgate_init; |
171 | g->railgate_delay = platform->railgate_delay_init; | ||
172 | g->ldiv_slowdown_factor = platform->ldiv_slowdown_factor_init; | 171 | g->ldiv_slowdown_factor = platform->ldiv_slowdown_factor_init; |
172 | /* if default delay is not set, set default delay to 500msec */ | ||
173 | if (platform->railgate_delay_init) | ||
174 | g->railgate_delay = platform->railgate_delay_init; | ||
175 | else | ||
176 | g->railgate_delay = NVGPU_DEFAULT_RAILGATE_IDLE_TIMEOUT; | ||
173 | __nvgpu_set_enabled(g, NVGPU_PMU_PERFMON, platform->enable_perfmon); | 177 | __nvgpu_set_enabled(g, NVGPU_PMU_PERFMON, platform->enable_perfmon); |
174 | 178 | ||
175 | /* set default values to aelpg parameters */ | 179 | /* set default values to aelpg parameters */ |
diff --git a/drivers/gpu/nvgpu/common/linux/module.c b/drivers/gpu/nvgpu/common/linux/module.c index 86abd36b..a7289b66 100644 --- a/drivers/gpu/nvgpu/common/linux/module.c +++ b/drivers/gpu/nvgpu/common/linux/module.c | |||
@@ -458,10 +458,10 @@ int __gk20a_do_idle(struct gk20a *g, bool force_reset) | |||
458 | * If User disables rail gating, we take one more | 458 | * If User disables rail gating, we take one more |
459 | * extra refcount | 459 | * extra refcount |
460 | */ | 460 | */ |
461 | if (g->user_railgate_disabled) | 461 | if (g->can_railgate) |
462 | target_ref_cnt = 2; | ||
463 | else | ||
464 | target_ref_cnt = 1; | 462 | target_ref_cnt = 1; |
463 | else | ||
464 | target_ref_cnt = 2; | ||
465 | nvgpu_mutex_acquire(&platform->railgate_lock); | 465 | nvgpu_mutex_acquire(&platform->railgate_lock); |
466 | 466 | ||
467 | nvgpu_timeout_init(g, &timeout, GK20A_WAIT_FOR_IDLE_MS, | 467 | nvgpu_timeout_init(g, &timeout, GK20A_WAIT_FOR_IDLE_MS, |
@@ -964,7 +964,7 @@ static int gk20a_pm_suspend(struct device *dev) | |||
964 | struct gk20a_platform *platform = dev_get_drvdata(dev); | 964 | struct gk20a_platform *platform = dev_get_drvdata(dev); |
965 | struct gk20a *g = get_gk20a(dev); | 965 | struct gk20a *g = get_gk20a(dev); |
966 | int ret = 0; | 966 | int ret = 0; |
967 | int idle_usage_count = g->user_railgate_disabled ? 1 : 0; | 967 | int idle_usage_count = 0; |
968 | 968 | ||
969 | if (!g->power_on) { | 969 | if (!g->power_on) { |
970 | if (!pm_runtime_enabled(dev)) | 970 | if (!pm_runtime_enabled(dev)) |
@@ -1020,23 +1020,19 @@ static int gk20a_pm_init(struct device *dev) | |||
1020 | 1020 | ||
1021 | nvgpu_log_fn(g, " "); | 1021 | nvgpu_log_fn(g, " "); |
1022 | 1022 | ||
1023 | /* Initialise pm runtime */ | 1023 | /* |
1024 | if (g->railgate_delay) { | 1024 | * Initialise pm runtime. For railgate disable |
1025 | * case, set autosuspend delay to negative which | ||
1026 | * will suspend runtime pm | ||
1027 | */ | ||
1028 | if (g->railgate_delay && g->can_railgate) | ||
1025 | pm_runtime_set_autosuspend_delay(dev, | 1029 | pm_runtime_set_autosuspend_delay(dev, |
1026 | g->railgate_delay); | 1030 | g->railgate_delay); |
1027 | pm_runtime_use_autosuspend(dev); | 1031 | else |
1028 | } | 1032 | pm_runtime_set_autosuspend_delay(dev, -1); |
1029 | 1033 | ||
1030 | if (g->can_railgate) { | 1034 | pm_runtime_use_autosuspend(dev); |
1031 | pm_runtime_enable(dev); | 1035 | pm_runtime_enable(dev); |
1032 | if (!pm_runtime_enabled(dev)) | ||
1033 | gk20a_pm_unrailgate(dev); | ||
1034 | else | ||
1035 | gk20a_pm_railgate(dev); | ||
1036 | } else { | ||
1037 | __pm_runtime_disable(dev, false); | ||
1038 | gk20a_pm_unrailgate(dev); | ||
1039 | } | ||
1040 | 1036 | ||
1041 | return err; | 1037 | return err; |
1042 | } | 1038 | } |
diff --git a/drivers/gpu/nvgpu/common/linux/sysfs.c b/drivers/gpu/nvgpu/common/linux/sysfs.c index e425e153..7a887beb 100644 --- a/drivers/gpu/nvgpu/common/linux/sysfs.c +++ b/drivers/gpu/nvgpu/common/linux/sysfs.c | |||
@@ -305,24 +305,23 @@ static ssize_t railgate_enable_store(struct device *dev, | |||
305 | unsigned long railgate_enable = 0; | 305 | unsigned long railgate_enable = 0; |
306 | /* dev is guaranteed to be valid here. Ok to de-reference */ | 306 | /* dev is guaranteed to be valid here. Ok to de-reference */ |
307 | struct gk20a *g = get_gk20a(dev); | 307 | struct gk20a *g = get_gk20a(dev); |
308 | int err = 0; | 308 | int err; |
309 | 309 | ||
310 | if (kstrtoul(buf, 10, &railgate_enable) < 0) | 310 | if (kstrtoul(buf, 10, &railgate_enable) < 0) |
311 | return -EINVAL; | 311 | return -EINVAL; |
312 | 312 | ||
313 | if (railgate_enable && !g->can_railgate) { | 313 | if (railgate_enable && !g->can_railgate) { |
314 | /* release extra ref count */ | ||
315 | gk20a_idle(g); | ||
316 | g->can_railgate = true; | 314 | g->can_railgate = true; |
317 | g->user_railgate_disabled = false; | 315 | pm_runtime_set_autosuspend_delay(dev, g->railgate_delay); |
318 | } else if (railgate_enable == 0 && g->can_railgate) { | 316 | } else if (railgate_enable == 0 && g->can_railgate) { |
319 | /* take extra ref count */ | ||
320 | err = gk20a_busy(g); | ||
321 | if (err) | ||
322 | return err; | ||
323 | g->can_railgate = false; | 317 | g->can_railgate = false; |
324 | g->user_railgate_disabled = true; | 318 | pm_runtime_set_autosuspend_delay(dev, -1); |
325 | } | 319 | } |
320 | /* wake-up system to make rail-gating setting effective */ | ||
321 | err = gk20a_busy(g); | ||
322 | if (err) | ||
323 | return err; | ||
324 | gk20a_idle(g); | ||
326 | 325 | ||
327 | nvgpu_info(g, "railgate is %s.", g->can_railgate ? | 326 | nvgpu_info(g, "railgate is %s.", g->can_railgate ? |
328 | "enabled" : "disabled"); | 327 | "enabled" : "disabled"); |