summaryrefslogtreecommitdiffstats
path: root/drivers
diff options
context:
space:
mode:
authorSeshendra Gadagottu <sgadagottu@nvidia.com>2015-09-24 16:16:33 -0400
committerTerje Bergstrom <tbergstrom@nvidia.com>2015-10-26 12:46:18 -0400
commit5c26f72fe18719a6639e1b6064eb013ec37b15ef (patch)
tree4c5f652ab80e72562317e9452d91e71007b05bf1 /drivers
parent3684ed8fd65ea3a13a99dc17c036899ba3165a44 (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')
-rw-r--r--drivers/gpu/nvgpu/gk20a/gk20a_sysfs.c64
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)
230static 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
274static 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
283static DEVICE_ATTR(railgate_enable, ROOTRW, railgate_enable_read,
284 railgate_enable_store);
285#endif
286
229static ssize_t railgate_delay_store(struct device *dev, 287static 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);