diff options
author | Seshendra Gadagottu <sgadagottu@nvidia.com> | 2015-09-24 16:16:33 -0400 |
---|---|---|
committer | Terje Bergstrom <tbergstrom@nvidia.com> | 2015-10-26 12:46:18 -0400 |
commit | 5c26f72fe18719a6639e1b6064eb013ec37b15ef (patch) | |
tree | 4c5f652ab80e72562317e9452d91e71007b05bf1 /drivers/gpu/nvgpu/gk20a | |
parent | 3684ed8fd65ea3a13a99dc17c036899ba3165a44 (diff) |
gpu: nvgpu: Add sysfs node to enable rail gating
Add sysfs node "railgate_enable" to enable
gpu railgating dynamically.
Bug 1552469
Reviewed-on: http://git-master/r/804746
(cherry picked from commit 53d76d1d1576a96c70f66b744411d2909ec8414f)
Change-Id: I69ac63958b00ae4ea5d9ccbaed03316d35ddc5eb
Signed-off-by: Seshendra Gadagottu <sgadagottu@nvidia.com>
Reviewed-on: http://git-master/r/822208
GVS: Gerrit_Virtual_Submit
Reviewed-by: Terje Bergstrom <tbergstrom@nvidia.com>
Diffstat (limited to 'drivers/gpu/nvgpu/gk20a')
-rw-r--r-- | drivers/gpu/nvgpu/gk20a/gk20a_sysfs.c | 64 |
1 files changed, 64 insertions, 0 deletions
diff --git a/drivers/gpu/nvgpu/gk20a/gk20a_sysfs.c b/drivers/gpu/nvgpu/gk20a/gk20a_sysfs.c index 996fe221..945b332d 100644 --- a/drivers/gpu/nvgpu/gk20a/gk20a_sysfs.c +++ b/drivers/gpu/nvgpu/gk20a/gk20a_sysfs.c | |||
@@ -226,6 +226,64 @@ static DEVICE_ATTR(ptimer_scale_factor, | |||
226 | ptimer_scale_factor_show, | 226 | ptimer_scale_factor_show, |
227 | NULL); | 227 | NULL); |
228 | 228 | ||
229 | #if defined(CONFIG_PM_RUNTIME) && defined(CONFIG_PM_GENERIC_DOMAINS) | ||
230 | static ssize_t railgate_enable_store(struct device *dev, | ||
231 | struct device_attribute *attr, const char *buf, size_t count) | ||
232 | { | ||
233 | struct gk20a_platform *platform = dev_get_drvdata(dev); | ||
234 | struct generic_pm_domain *genpd = dev_to_genpd(dev); | ||
235 | struct platform_device *ndev = to_platform_device(dev); | ||
236 | struct gk20a *g = get_gk20a(ndev); | ||
237 | unsigned long railgate_enable = 0; | ||
238 | int err; | ||
239 | |||
240 | if (kstrtoul(buf, 10, &railgate_enable) < 0) | ||
241 | return -EINVAL; | ||
242 | if (railgate_enable && !platform->can_railgate) { | ||
243 | mutex_lock(&platform->railgate_lock); | ||
244 | platform->can_railgate = true; | ||
245 | genpd->gov = NULL; | ||
246 | pm_genpd_set_poweroff_delay(genpd, platform->railgate_delay); | ||
247 | /* release extra ref count:if power domains not enabled */ | ||
248 | if ((platform->railgate) && \ | ||
249 | !IS_ENABLED(CONFIG_PM_GENERIC_DOMAINS)) | ||
250 | err = platform->railgate(ndev); | ||
251 | mutex_unlock(&platform->railgate_lock); | ||
252 | } else if (railgate_enable == 0 && platform->can_railgate) { | ||
253 | mutex_lock(&platform->railgate_lock); | ||
254 | platform->can_railgate = false; | ||
255 | genpd->gov = &pm_domain_always_on_gov; | ||
256 | pm_genpd_set_poweroff_delay(genpd, platform->railgate_delay); | ||
257 | /* take extra ref count - incase of power domains not enabled */ | ||
258 | if ((platform->unrailgate) && \ | ||
259 | !IS_ENABLED(CONFIG_PM_GENERIC_DOMAINS)) | ||
260 | err = platform->unrailgate(ndev); | ||
261 | mutex_unlock(&platform->railgate_lock); | ||
262 | } | ||
263 | dev_info(dev, "railgate is %s.\n", platform->can_railgate ? | ||
264 | "enabled" : "disabled"); | ||
265 | /* wake-up system to make railgating_enable effective immediately */ | ||
266 | err = gk20a_busy(g->dev); | ||
267 | if (err) | ||
268 | return err; | ||
269 | gk20a_idle(g->dev); | ||
270 | |||
271 | return count; | ||
272 | } | ||
273 | |||
274 | static ssize_t railgate_enable_read(struct device *device, | ||
275 | struct device_attribute *attr, char *buf) | ||
276 | { | ||
277 | struct platform_device *ndev = to_platform_device(device); | ||
278 | struct gk20a_platform *platform = dev_get_drvdata(&ndev->dev); | ||
279 | |||
280 | return sprintf(buf, "%d\n", platform->can_railgate ? 1 : 0); | ||
281 | } | ||
282 | |||
283 | static DEVICE_ATTR(railgate_enable, ROOTRW, railgate_enable_read, | ||
284 | railgate_enable_store); | ||
285 | #endif | ||
286 | |||
229 | static ssize_t railgate_delay_store(struct device *dev, | 287 | static ssize_t railgate_delay_store(struct device *dev, |
230 | struct device_attribute *attr, | 288 | struct device_attribute *attr, |
231 | const char *buf, size_t count) | 289 | const char *buf, size_t count) |
@@ -711,6 +769,9 @@ void gk20a_remove_sysfs(struct device *dev) | |||
711 | device_remove_file(dev, &dev_attr_clockgate_delay); | 769 | device_remove_file(dev, &dev_attr_clockgate_delay); |
712 | #ifdef CONFIG_PM_RUNTIME | 770 | #ifdef CONFIG_PM_RUNTIME |
713 | device_remove_file(dev, &dev_attr_force_idle); | 771 | device_remove_file(dev, &dev_attr_force_idle); |
772 | #if defined(CONFIG_PM_GENERIC_DOMAINS) | ||
773 | device_remove_file(dev, &dev_attr_railgate_enable); | ||
774 | #endif | ||
714 | #endif | 775 | #endif |
715 | device_remove_file(dev, &dev_attr_aelpg_param); | 776 | device_remove_file(dev, &dev_attr_aelpg_param); |
716 | device_remove_file(dev, &dev_attr_aelpg_enable); | 777 | device_remove_file(dev, &dev_attr_aelpg_enable); |
@@ -741,6 +802,9 @@ void gk20a_create_sysfs(struct platform_device *dev) | |||
741 | error |= device_create_file(&dev->dev, &dev_attr_clockgate_delay); | 802 | error |= device_create_file(&dev->dev, &dev_attr_clockgate_delay); |
742 | #ifdef CONFIG_PM_RUNTIME | 803 | #ifdef CONFIG_PM_RUNTIME |
743 | error |= device_create_file(&dev->dev, &dev_attr_force_idle); | 804 | error |= device_create_file(&dev->dev, &dev_attr_force_idle); |
805 | #if defined(CONFIG_PM_GENERIC_DOMAINS) | ||
806 | error |= device_create_file(&dev->dev, &dev_attr_railgate_enable); | ||
807 | #endif | ||
744 | #endif | 808 | #endif |
745 | error |= device_create_file(&dev->dev, &dev_attr_aelpg_param); | 809 | error |= device_create_file(&dev->dev, &dev_attr_aelpg_param); |
746 | error |= device_create_file(&dev->dev, &dev_attr_aelpg_enable); | 810 | error |= device_create_file(&dev->dev, &dev_attr_aelpg_enable); |