From fe7368f8f40a3d1ae6337642b811fcfc29dc4ecc Mon Sep 17 00:00:00 2001 From: Mayur Poojary Date: Wed, 8 Sep 2021 19:15:07 +0530 Subject: [PATCH] gpu: nvgpu: ga10b: Support emulate mode Add sysfs node to enable gpu emulate_mode and pass the value to acr through acr descriptor struct. Bug 3279344 Change-Id: I936b1dda84d7f4f3688237308223c019798bdce3 Signed-off-by: Mayur Poojary Reviewed-on: https://git-master.nvidia.com/r/c/linux-nvgpu/+/2591377 Tested-by: mobile promotions Reviewed-by: mobile promotions --- drivers/gpu/nvgpu/common/acr/acr_sw_ga10b.c | 6 +++ .../nvgpu/common/acr/nvgpu_acr_interface.h | 7 ++++ drivers/gpu/nvgpu/include/nvgpu/gk20a.h | 3 ++ drivers/gpu/nvgpu/include/nvgpu/grmgr.h | 9 +++++ drivers/gpu/nvgpu/os/linux/sysfs.c | 37 +++++++++++++++++++ 5 files changed, 62 insertions(+) diff --git a/drivers/gpu/nvgpu/common/acr/acr_sw_ga10b.c b/drivers/gpu/nvgpu/common/acr/acr_sw_ga10b.c index feb686c94..204cd05b2 100644 --- a/drivers/gpu/nvgpu/common/acr/acr_sw_ga10b.c +++ b/drivers/gpu/nvgpu/common/acr/acr_sw_ga10b.c @@ -25,6 +25,7 @@ #include #include #include +#include #ifdef CONFIG_NVGPU_LS_PMU #include #endif @@ -154,6 +155,11 @@ static int ga10b_acr_patch_wpr_info_to_ucode(struct gk20a *g, * Offset from the WPR region holding the wpr header */ acr_sysmem_desc->wpr_offset = WPR_OFFSET; + + if (g->emulate_mode < EMULATE_MODE_MAX_CONFIG) { + acr_sysmem_desc->gpu_mode &= (~EMULATE_MODE_MASK); + acr_sysmem_desc->gpu_mode |= g->emulate_mode; + } } load: /* diff --git a/drivers/gpu/nvgpu/common/acr/nvgpu_acr_interface.h b/drivers/gpu/nvgpu/common/acr/nvgpu_acr_interface.h index e70d6a3fc..106fe137f 100644 --- a/drivers/gpu/nvgpu/common/acr/nvgpu_acr_interface.h +++ b/drivers/gpu/nvgpu/common/acr/nvgpu_acr_interface.h @@ -775,6 +775,13 @@ struct flcn2_acr_desc { u64 nonwpr_ucode_blob_start; u64 ls_pmu_desc; + + /** + * stores flag value to enable: + * emulate_mode 7:0 bit + * MIG mode 15:8 bit + */ + u32 gpu_mode; }; /** @} */ diff --git a/drivers/gpu/nvgpu/include/nvgpu/gk20a.h b/drivers/gpu/nvgpu/include/nvgpu/gk20a.h index 59b2f6650..c5735abb9 100644 --- a/drivers/gpu/nvgpu/include/nvgpu/gk20a.h +++ b/drivers/gpu/nvgpu/include/nvgpu/gk20a.h @@ -833,6 +833,9 @@ struct gk20a { /** Cache to store IPA to PA translations. */ struct nvgpu_ipa_pa_cache ipa_pa_cache; #endif + + /** To enable emulate mode */ + u32 emulate_mode; }; /** diff --git a/drivers/gpu/nvgpu/include/nvgpu/grmgr.h b/drivers/gpu/nvgpu/include/nvgpu/grmgr.h index fc8148f73..67583dd85 100644 --- a/drivers/gpu/nvgpu/include/nvgpu/grmgr.h +++ b/drivers/gpu/nvgpu/include/nvgpu/grmgr.h @@ -30,6 +30,15 @@ #include #include +#define EMULATE_MODE_MASK 0X000000FFU + +enum emulate_mode_config { + EMULATE_MODE_DISABLE = 0U, + EMULATE_MODE_1_GPC = 1U, + EMULATE_MODE_2_GPC = 2U, + EMULATE_MODE_MAX_CONFIG = 3U +}; + struct gk20a; int nvgpu_init_gr_manager(struct gk20a *g); diff --git a/drivers/gpu/nvgpu/os/linux/sysfs.c b/drivers/gpu/nvgpu/os/linux/sysfs.c index 0f833b2fe..c95f0c124 100644 --- a/drivers/gpu/nvgpu/os/linux/sysfs.c +++ b/drivers/gpu/nvgpu/os/linux/sysfs.c @@ -1170,6 +1170,41 @@ static DEVICE_ATTR(mig_mode_config, ROOTRW, #endif +static ssize_t emulate_mode_store(struct device *dev, + struct device_attribute *attr, const char *buf, size_t count) +{ + struct gk20a *g = get_gk20a(dev); + unsigned long val = 0; + + if (kstrtoul(buf, 10, &val) < 0) + return -EINVAL; + + if (nvgpu_is_powered_on(g)) { + nvgpu_err(g, "GPU is powered on already, emulate mode " + "cannot be enabled"); + return -EINVAL; + } + + if (val < EMULATE_MODE_MAX_CONFIG) { + g->emulate_mode = val; + nvgpu_info(g, "emulate mode is set to %d.", g->emulate_mode); + } else { + nvgpu_err(g, "Unsupported emulate_mode %lx", val); + } + + return count; +} + +static ssize_t emulate_mode_read(struct device *dev, + struct device_attribute *attr, char *buf) +{ + struct gk20a *g = get_gk20a(dev); + + return snprintf(buf, NVGPU_CPU_PAGE_SIZE, "%d\n", g->emulate_mode); +} + +static DEVICE_ATTR(emulate_mode, ROOTRW, emulate_mode_read, emulate_mode_store); + void nvgpu_remove_sysfs(struct device *dev) { device_remove_file(dev, &dev_attr_elcg_enable); @@ -1215,6 +1250,7 @@ void nvgpu_remove_sysfs(struct device *dev) device_remove_file(dev, &dev_attr_mig_mode_config_list); device_remove_file(dev, &dev_attr_mig_mode_config); #endif + device_remove_file(dev, &dev_attr_emulate_mode); if (strcmp(dev_name(dev), "gpu.0")) { struct kobject *kobj = &dev->kobj; struct device *parent = container_of((kobj->parent), @@ -1279,6 +1315,7 @@ int nvgpu_create_sysfs(struct device *dev) error |= device_create_file(dev, &dev_attr_mig_mode_config_list); error |= device_create_file(dev, &dev_attr_mig_mode_config); #endif + error |= device_create_file(dev, &dev_attr_emulate_mode); if (strcmp(dev_name(dev), "gpu.0")) { struct kobject *kobj = &dev->kobj; struct device *parent = container_of((kobj->parent),