From 70bf8275efab7e155e9b3f9853a4cf7f38228c43 Mon Sep 17 00:00:00 2001 From: Kirill Artamonov Date: Mon, 12 Feb 2018 15:02:52 +0200 Subject: gpu: nvgpu: gv11b: implement gfxp wfi controls /sys/devices/gpu.0/gfxp_wfi_timeout_unit usec - microseconds sysclk - gpu clock count Treat gr_fe_gfxp_wfi_timeout_r as context-switched register on gv11b. Set default gfxp_wfi_timeout to 100 usec to match gp10b at 1GHz. bug 1888344 Signed-off-by: Kirill Artamonov Change-Id: I7fa64ce6912ae861244856807543b17bd7a26bed Reviewed-on: https://git-master.nvidia.com/r/1651517 Reviewed-by: mobile promotions Tested-by: mobile promotions --- drivers/gpu/nvgpu/common/linux/sysfs.c | 47 ++++++++++++++++++++++++++++++++++ drivers/gpu/nvgpu/gk20a/gr_gk20a.h | 1 + drivers/gpu/nvgpu/gv11b/gr_gv11b.c | 29 ++++++++++++++------- drivers/gpu/nvgpu/gv11b/gr_gv11b.h | 3 +++ 4 files changed, 71 insertions(+), 9 deletions(-) diff --git a/drivers/gpu/nvgpu/common/linux/sysfs.c b/drivers/gpu/nvgpu/common/linux/sysfs.c index afa08fc4..6709285d 100644 --- a/drivers/gpu/nvgpu/common/linux/sysfs.c +++ b/drivers/gpu/nvgpu/common/linux/sysfs.c @@ -28,6 +28,7 @@ #include "platform_gk20a.h" #include "gk20a/pmu_gk20a.h" #include "gk20a/gr_gk20a.h" +#include "gv11b/gr_gv11b.h" #define PTIMER_FP_FACTOR 1000000 @@ -977,6 +978,36 @@ static ssize_t gfxp_wfi_timeout_count_store(struct device *dev, 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_unit_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; + int err = -1; + + if (count > 0 && buf[0] == 's') + /* sysclk */ + gr->gfxp_wfi_timeout_unit = GFXP_WFI_TIMEOUT_UNIT_SYSCLK; + else + /* usec */ + gr->gfxp_wfi_timeout_unit = GFXP_WFI_TIMEOUT_UNIT_USEC; + if (g->ops.gr.init_preemption_state && g->power_on) { err = gk20a_busy(g); if (err) @@ -1004,9 +1035,23 @@ static ssize_t gfxp_wfi_timeout_count_read(struct device *dev, return snprintf(buf, PAGE_SIZE, "%d\n", val); } +static ssize_t gfxp_wfi_timeout_unit_read(struct device *dev, + struct device_attribute *attr, char *buf) +{ + struct gk20a *g = get_gk20a(dev); + struct gr_gk20a *gr = &g->gr; + + if (gr->gfxp_wfi_timeout_unit == GFXP_WFI_TIMEOUT_UNIT_USEC) + return snprintf(buf, PAGE_SIZE, "usec\n"); + else + return snprintf(buf, PAGE_SIZE, "sysclk\n"); +} + static DEVICE_ATTR(gfxp_wfi_timeout_count, (S_IRWXU|S_IRGRP|S_IROTH), gfxp_wfi_timeout_count_read, gfxp_wfi_timeout_count_store); +static DEVICE_ATTR(gfxp_wfi_timeout_unit, (S_IRWXU|S_IRGRP|S_IROTH), + gfxp_wfi_timeout_unit_read, gfxp_wfi_timeout_unit_store); void nvgpu_remove_sysfs(struct device *dev) { @@ -1045,6 +1090,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); + device_remove_file(dev, &dev_attr_gfxp_wfi_timeout_unit); if (strcmp(dev_name(dev), "gpu.0")) { struct kobject *kobj = &dev->kobj; @@ -1094,6 +1140,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); + error |= device_create_file(dev, &dev_attr_gfxp_wfi_timeout_unit); if (strcmp(dev_name(dev), "gpu.0")) { struct kobject *kobj = &dev->kobj; diff --git a/drivers/gpu/nvgpu/gk20a/gr_gk20a.h b/drivers/gpu/nvgpu/gk20a/gr_gk20a.h index 5c638a8d..3fcba678 100644 --- a/drivers/gpu/nvgpu/gk20a/gr_gk20a.h +++ b/drivers/gpu/nvgpu/gk20a/gr_gk20a.h @@ -377,6 +377,7 @@ struct gr_gk20a { u32 czf_bypass; u32 pd_max_batches; u32 gfxp_wfi_timeout_count; + u32 gfxp_wfi_timeout_unit; struct gr_ctx_buffer_desc global_ctx_buffer[NR_GLOBAL_CTX_BUF]; diff --git a/drivers/gpu/nvgpu/gv11b/gr_gv11b.c b/drivers/gpu/nvgpu/gv11b/gr_gv11b.c index dee3b760..808cf19f 100644 --- a/drivers/gpu/nvgpu/gv11b/gr_gv11b.c +++ b/drivers/gpu/nvgpu/gv11b/gr_gv11b.c @@ -56,7 +56,7 @@ #include #include -#define GFXP_WFI_TIMEOUT_COUNT_IN_USEC_DEFAULT 1000 +#define GFXP_WFI_TIMEOUT_COUNT_IN_USEC_DEFAULT 100 /* ecc scrubbing will done in 1 pri read cycle,but for safety used 10 retries */ #define ECC_SCRUBBING_TIMEOUT_MAX 1000 @@ -1663,6 +1663,11 @@ void gr_gv11b_update_ctxsw_preemption_mode(struct gk20a *g, cbes_reserve), true); + gr_gk20a_ctx_patch_write(g, gr_ctx, + gr_fe_gfxp_wfi_timeout_r(), + g->gr.gfxp_wfi_timeout_count, + true); + gr_gk20a_ctx_patch_write_end(g, gr_ctx, true); } @@ -4099,17 +4104,19 @@ int gr_gv11b_init_preemption_state(struct gk20a *g) { u32 debug_2; struct gr_gk20a *gr = &g->gr; + u32 unit; nvgpu_log_fn(g, " "); - gk20a_writel(g, gr_fe_gfxp_wfi_timeout_r(), - gr_fe_gfxp_wfi_timeout_count_f( - gr->gfxp_wfi_timeout_count)); + if (gr->gfxp_wfi_timeout_unit == GFXP_WFI_TIMEOUT_UNIT_USEC) + unit = gr_debug_2_gfxp_wfi_timeout_unit_usec_f(); + else + unit = gr_debug_2_gfxp_wfi_timeout_unit_sysclk_f(); debug_2 = gk20a_readl(g, gr_debug_2_r()); debug_2 = set_field(debug_2, - gr_debug_2_gfxp_wfi_timeout_unit_m(), - gr_debug_2_gfxp_wfi_timeout_unit_usec_f()); + gr_debug_2_gfxp_wfi_timeout_unit_m(), + unit); gk20a_writel(g, gr_debug_2_r(), debug_2); return 0; @@ -4117,14 +4124,18 @@ int gr_gv11b_init_preemption_state(struct gk20a *g) void gr_gv11b_init_gfxp_wfi_timeout_count(struct gk20a *g) { struct gr_gk20a *gr = &g->gr; - + gr->gfxp_wfi_timeout_unit = GFXP_WFI_TIMEOUT_UNIT_USEC; gr->gfxp_wfi_timeout_count = GFXP_WFI_TIMEOUT_COUNT_IN_USEC_DEFAULT; } unsigned long gr_gv11b_get_max_gfxp_wfi_timeout_count(struct gk20a *g) { - /* 100 msec in usec count */ - return (100 * 1000UL); + if (g->gr.gfxp_wfi_timeout_unit == GFXP_WFI_TIMEOUT_UNIT_USEC) + /* 100 msec in usec count */ + return (100UL * 1000UL); + else + /* 100 msec for 1GHz clock */ + return (100UL * 1000UL * 1000UL); } static int gr_gv11b_ecc_scrub_is_done(struct gk20a *g, diff --git a/drivers/gpu/nvgpu/gv11b/gr_gv11b.h b/drivers/gpu/nvgpu/gv11b/gr_gv11b.h index 2f8d2e17..0f42e795 100644 --- a/drivers/gpu/nvgpu/gv11b/gr_gv11b.h +++ b/drivers/gpu/nvgpu/gv11b/gr_gv11b.h @@ -34,6 +34,9 @@ #define ZBC_STENCIL_CLEAR_FMT_INVAILD 0 #define ZBC_STENCIL_CLEAR_FMT_U8 1 +#define GFXP_WFI_TIMEOUT_UNIT_SYSCLK 0 +#define GFXP_WFI_TIMEOUT_UNIT_USEC 1 + struct gk20a; struct gr_gk20a; struct zbc_entry; -- cgit v1.2.2