From 00e52529a8431a6520b8e1bbcbfa44b4cc86be80 Mon Sep 17 00:00:00 2001 From: Jonathan McCaffrey Date: Thu, 17 Aug 2017 23:51:03 -0700 Subject: gpu: gp10b: add gfxp_wfi_timeout sysfs node Add a sysfs node to allow root user to set PRI_FE_GFXP_WFI_TIMEOUT, for gp10b only, in units of sysclk cycles. Store the set value in a variable, and write the set value to register after GPU is un-railgated. NV_PGRAPH_PRI_FE_GFXP_WFI_TIMEOUT is engine_reset after Bug 1623341. Change default value to be specified in cycles, rather than time. This value is almost the current value in cycles calculated each boot. Bug 1932782 Change-Id: I0a4207e637cd1413a1be95abe2bcce3adccf76fa Reviewed-on: https://git-master.nvidia.com/r/1540939 Signed-off-by: Jonathan McCaffrey Reviewed-on: https://git-master.nvidia.com/r/1580999 Reviewed-by: mobile promotions Tested-by: mobile promotions --- drivers/gpu/nvgpu/common/linux/sysfs.c | 48 ++++++++++++++++++++++++++++++++++ 1 file changed, 48 insertions(+) (limited to 'drivers/gpu/nvgpu/common/linux/sysfs.c') diff --git a/drivers/gpu/nvgpu/common/linux/sysfs.c b/drivers/gpu/nvgpu/common/linux/sysfs.c index 7b614023..6897fae8 100644 --- a/drivers/gpu/nvgpu/common/linux/sysfs.c +++ b/drivers/gpu/nvgpu/common/linux/sysfs.c @@ -954,6 +954,52 @@ static ssize_t pd_max_batches_read(struct device *dev, static DEVICE_ATTR(pd_max_batches, ROOTRW, pd_max_batches_read, pd_max_batches_store); +static ssize_t gfxp_wfi_timeout_count_store(struct device *dev, + struct device_attribute *attr, const char *buf, size_t count) +{ + struct gk20a *g = get_gk20a(dev); + struct gr_gk20a *gr = &g->gr; + unsigned long val = 0; + int err = -1; + + if (kstrtoul(buf, 10, &val) < 0) + return -EINVAL; + + if (val >= 100*1000*1000) /* 100ms @ 1Ghz */ + return -EINVAL; + + gr->gfxp_wfi_timeout_count = val; + + if (g->ops.gr.init_preemption_state && g->power_on) { + err = gk20a_busy(g); + if (err) + return err; + + err = gr_gk20a_elpg_protected_call(g, + g->ops.gr.init_preemption_state(g)); + + gk20a_idle(g); + + if (err) + return err; + } + + return count; +} + +static ssize_t gfxp_wfi_timeout_count_read(struct device *dev, + struct device_attribute *attr, char *buf) +{ + struct gk20a *g = get_gk20a(dev); + struct gr_gk20a *gr = &g->gr; + u32 val = gr->gfxp_wfi_timeout_count; + + return snprintf(buf, PAGE_SIZE, "%d\n", val); +} + +static DEVICE_ATTR(gfxp_wfi_timeout_count, (S_IRWXU|S_IRGRP|S_IROTH), + gfxp_wfi_timeout_count_read, gfxp_wfi_timeout_count_store); + void nvgpu_remove_sysfs(struct device *dev) { @@ -989,6 +1035,7 @@ void nvgpu_remove_sysfs(struct device *dev) device_remove_file(dev, &dev_attr_czf_bypass); device_remove_file(dev, &dev_attr_pd_max_batches); + device_remove_file(dev, &dev_attr_gfxp_wfi_timeout_count); if (strcmp(dev_name(dev), "gpu.0")) { struct kobject *kobj = &dev->kobj; @@ -1035,6 +1082,7 @@ int nvgpu_create_sysfs(struct device *dev) error |= device_create_file(dev, &dev_attr_czf_bypass); error |= device_create_file(dev, &dev_attr_pd_max_batches); + error |= device_create_file(dev, &dev_attr_gfxp_wfi_timeout_count); if (strcmp(dev_name(dev), "gpu.0")) { struct kobject *kobj = &dev->kobj; -- cgit v1.2.2