diff options
author | Deepak Nibade <dnibade@nvidia.com> | 2016-06-09 09:16:21 -0400 |
---|---|---|
committer | Terje Bergstrom <tbergstrom@nvidia.com> | 2016-07-08 03:58:53 -0400 |
commit | e27c72446bf09196d6d66f28389f00565273a13f (patch) | |
tree | 473530a0f10eee8d9dcae29afdc35c72b7a6a0ad /drivers/gpu/nvgpu/gk20a/gk20a_sysfs.c | |
parent | 8417698b519be9dc8c1bd04714fc72ce4e0bc38f (diff) |
gpu: nvgpu: simplify power management
We currenlty initialize both runtime PM and pm_domains frameworks
and use pm_domain to control runtime power management of NvGPU
But since GPU has a separate rail, using pm_domain is not
strictly required
Hence remove pm_domain support and use runtime PM only for all
the power management
This also simplifies the code a lot
Initialization in gk20a_pm_init()
- if railgate_delay is set, set autosuspend delay of runtime PM
- try enabling runtime PM
- if runtime PM is now enabled, keep GPU railgated
- if runtime PM is not enabled, keep GPU unrailgated
- if can_railgate = false, disable runtime PM and keep
GPU unrailgated
Set gk20a_pm_ops with below callbacks for runtime PM
static const struct dev_pm_ops gk20a_pm_ops = {
.runtime_resume = gk20a_pm_runtime_resume,
.runtime_suspend = gk20a_pm_runtime_suspend,
.resume = gk20a_pm_resume,
.suspend = gk20a_pm_suspend,
}
Move gk20a_busy() to use runtime checks of pm_runtime_enabled()
instead of using compile time checks on CONFIG_PM
Clean up some pm_domain related code
Remove use of gk20a_pm_enable/disable_clk() since this
should be already done in platform specific unrailgate()/
railgate() APIs
Fix "railgate_delay" and "railgate_enable" sysfs to use
runtime PM calls
For VGPU, disable runtime PM during vgpu_pm_init()
With this, we will initialize vgpu with vgpu_pm_finalize_poweron()
upon first call to gk20a_busy()
Jira DNVGPU-57
Change-Id: I6013e33ae9bd28f35c25271af1239942a4fa0919
Signed-off-by: Deepak Nibade <dnibade@nvidia.com>
Reviewed-on: http://git-master/r/1163216
Reviewed-by: Automatic_Commit_Validation_User
GVS: Gerrit_Virtual_Submit
Reviewed-by: Terje Bergstrom <tbergstrom@nvidia.com>
Diffstat (limited to 'drivers/gpu/nvgpu/gk20a/gk20a_sysfs.c')
-rw-r--r-- | drivers/gpu/nvgpu/gk20a/gk20a_sysfs.c | 40 |
1 files changed, 10 insertions, 30 deletions
diff --git a/drivers/gpu/nvgpu/gk20a/gk20a_sysfs.c b/drivers/gpu/nvgpu/gk20a/gk20a_sysfs.c index 127d0258..38d5a842 100644 --- a/drivers/gpu/nvgpu/gk20a/gk20a_sysfs.c +++ b/drivers/gpu/nvgpu/gk20a/gk20a_sysfs.c | |||
@@ -276,49 +276,33 @@ static DEVICE_ATTR(ptimer_src_freq, | |||
276 | NULL); | 276 | NULL); |
277 | 277 | ||
278 | 278 | ||
279 | #if defined(CONFIG_PM) && defined(CONFIG_PM_GENERIC_DOMAINS) | 279 | #if defined(CONFIG_PM) |
280 | static ssize_t railgate_enable_store(struct device *dev, | 280 | static ssize_t railgate_enable_store(struct device *dev, |
281 | struct device_attribute *attr, const char *buf, size_t count) | 281 | struct device_attribute *attr, const char *buf, size_t count) |
282 | { | 282 | { |
283 | struct gk20a_platform *platform = dev_get_drvdata(dev); | 283 | struct gk20a_platform *platform = dev_get_drvdata(dev); |
284 | struct generic_pm_domain *genpd = dev_to_genpd(dev); | ||
285 | struct gk20a *g = get_gk20a(dev); | ||
286 | unsigned long railgate_enable = 0; | 284 | unsigned long railgate_enable = 0; |
287 | int err = 0; | 285 | int err = 0; |
288 | 286 | ||
289 | if (kstrtoul(buf, 10, &railgate_enable) < 0) | 287 | if (kstrtoul(buf, 10, &railgate_enable) < 0) |
290 | return -EINVAL; | 288 | return -EINVAL; |
289 | |||
291 | if (railgate_enable && !platform->can_railgate) { | 290 | if (railgate_enable && !platform->can_railgate) { |
292 | mutex_lock(&platform->railgate_lock); | 291 | /* release extra ref count */ |
292 | gk20a_idle(dev); | ||
293 | platform->can_railgate = true; | 293 | platform->can_railgate = true; |
294 | genpd->gov = NULL; | ||
295 | pm_genpd_set_poweroff_delay(genpd, platform->railgate_delay); | ||
296 | /* release extra ref count:if power domains not enabled */ | ||
297 | if ((platform->railgate) && \ | ||
298 | !IS_ENABLED(CONFIG_PM_GENERIC_DOMAINS)) | ||
299 | err = platform->railgate(dev); | ||
300 | mutex_unlock(&platform->railgate_lock); | ||
301 | } else if (railgate_enable == 0 && platform->can_railgate) { | 294 | } else if (railgate_enable == 0 && platform->can_railgate) { |
302 | mutex_lock(&platform->railgate_lock); | 295 | /* take extra ref count */ |
296 | err = gk20a_busy(dev); | ||
297 | if (err) | ||
298 | return err; | ||
303 | platform->can_railgate = false; | 299 | platform->can_railgate = false; |
304 | genpd->gov = &pm_domain_always_on_gov; | ||
305 | pm_genpd_set_poweroff_delay(genpd, platform->railgate_delay); | ||
306 | /* take extra ref count - incase of power domains not enabled */ | ||
307 | if ((platform->unrailgate) && \ | ||
308 | !IS_ENABLED(CONFIG_PM_GENERIC_DOMAINS)) | ||
309 | err = platform->unrailgate(dev); | ||
310 | mutex_unlock(&platform->railgate_lock); | ||
311 | } | 300 | } |
312 | if (err) | 301 | if (err) |
313 | return err; | 302 | return err; |
314 | 303 | ||
315 | dev_info(dev, "railgate is %s.\n", platform->can_railgate ? | 304 | dev_info(dev, "railgate is %s.\n", platform->can_railgate ? |
316 | "enabled" : "disabled"); | 305 | "enabled" : "disabled"); |
317 | /* wake-up system to make railgating_enable effective immediately */ | ||
318 | err = gk20a_busy(g->dev); | ||
319 | if (err) | ||
320 | return err; | ||
321 | gk20a_idle(g->dev); | ||
322 | 306 | ||
323 | return count; | 307 | return count; |
324 | } | 308 | } |
@@ -351,11 +335,11 @@ static ssize_t railgate_delay_store(struct device *dev, | |||
351 | 335 | ||
352 | ret = sscanf(buf, "%d", &railgate_delay); | 336 | ret = sscanf(buf, "%d", &railgate_delay); |
353 | if (ret == 1 && railgate_delay >= 0) { | 337 | if (ret == 1 && railgate_delay >= 0) { |
354 | struct generic_pm_domain *genpd = pd_to_genpd(dev->pm_domain); | ||
355 | platform->railgate_delay = railgate_delay; | 338 | platform->railgate_delay = railgate_delay; |
356 | pm_genpd_set_poweroff_delay(genpd, platform->railgate_delay); | 339 | pm_runtime_set_autosuspend_delay(dev, platform->railgate_delay); |
357 | } else | 340 | } else |
358 | dev_err(dev, "Invalid powergate delay\n"); | 341 | dev_err(dev, "Invalid powergate delay\n"); |
342 | |||
359 | /* wake-up system to make rail-gating delay effective immediately */ | 343 | /* wake-up system to make rail-gating delay effective immediately */ |
360 | err = gk20a_busy(g->dev); | 344 | err = gk20a_busy(g->dev); |
361 | if (err) | 345 | if (err) |
@@ -782,10 +766,8 @@ void gk20a_remove_sysfs(struct device *dev) | |||
782 | device_remove_file(dev, &dev_attr_is_railgated); | 766 | device_remove_file(dev, &dev_attr_is_railgated); |
783 | #ifdef CONFIG_PM | 767 | #ifdef CONFIG_PM |
784 | device_remove_file(dev, &dev_attr_force_idle); | 768 | device_remove_file(dev, &dev_attr_force_idle); |
785 | #if defined(CONFIG_PM_GENERIC_DOMAINS) | ||
786 | device_remove_file(dev, &dev_attr_railgate_enable); | 769 | device_remove_file(dev, &dev_attr_railgate_enable); |
787 | #endif | 770 | #endif |
788 | #endif | ||
789 | device_remove_file(dev, &dev_attr_aelpg_param); | 771 | device_remove_file(dev, &dev_attr_aelpg_param); |
790 | device_remove_file(dev, &dev_attr_aelpg_enable); | 772 | device_remove_file(dev, &dev_attr_aelpg_enable); |
791 | device_remove_file(dev, &dev_attr_allow_all); | 773 | device_remove_file(dev, &dev_attr_allow_all); |
@@ -823,10 +805,8 @@ void gk20a_create_sysfs(struct device *dev) | |||
823 | error |= device_create_file(dev, &dev_attr_is_railgated); | 805 | error |= device_create_file(dev, &dev_attr_is_railgated); |
824 | #ifdef CONFIG_PM | 806 | #ifdef CONFIG_PM |
825 | error |= device_create_file(dev, &dev_attr_force_idle); | 807 | error |= device_create_file(dev, &dev_attr_force_idle); |
826 | #if defined(CONFIG_PM_GENERIC_DOMAINS) | ||
827 | error |= device_create_file(dev, &dev_attr_railgate_enable); | 808 | error |= device_create_file(dev, &dev_attr_railgate_enable); |
828 | #endif | 809 | #endif |
829 | #endif | ||
830 | error |= device_create_file(dev, &dev_attr_aelpg_param); | 810 | error |= device_create_file(dev, &dev_attr_aelpg_param); |
831 | error |= device_create_file(dev, &dev_attr_aelpg_enable); | 811 | error |= device_create_file(dev, &dev_attr_aelpg_enable); |
832 | error |= device_create_file(dev, &dev_attr_allow_all); | 812 | error |= device_create_file(dev, &dev_attr_allow_all); |