From be5a82b73ec4823297210c88118904ce606c1867 Mon Sep 17 00:00:00 2001 From: Sagar Kamble Date: Wed, 7 Aug 2019 22:10:22 +0530 Subject: [PATCH] gpu: nvgpu: userspace: cg unit tests Add unit tests for verifying the blcg and slcg prod values loading interfaces. JIRA NVGPU-2175 Change-Id: Ia48f3fe9ce463e47f819d15aa64e120040a31fb4 Signed-off-by: Sagar Kamble Reviewed-on: https://git-master.nvidia.com/r/2173829 GVS: Gerrit_Virtual_Submit Reviewed-by: Vijayakumar Subbu Reviewed-by: mobile promotions Tested-by: mobile promotions --- Makefile.umbrella.tmk | 1 + drivers/gpu/nvgpu/libnvgpu-drv_safe.export | 55 +++ userspace/Makefile.sources | 5 +- userspace/SWUTS.h | 1 + userspace/SWUTS.sources | 1 + userspace/required_tests.json | 65 +++ userspace/units/cg/Makefile | 26 ++ userspace/units/cg/Makefile.interface.tmk | 34 ++ userspace/units/cg/Makefile.tmk | 36 ++ userspace/units/cg/nvgpu-cg.c | 445 +++++++++++++++++++++ userspace/units/cg/nvgpu-cg.h | 67 ++++ 11 files changed, 734 insertions(+), 2 deletions(-) create mode 100644 userspace/units/cg/Makefile create mode 100644 userspace/units/cg/Makefile.interface.tmk create mode 100644 userspace/units/cg/Makefile.tmk create mode 100644 userspace/units/cg/nvgpu-cg.c create mode 100644 userspace/units/cg/nvgpu-cg.h diff --git a/Makefile.umbrella.tmk b/Makefile.umbrella.tmk index db34360f1..f7ef2c51f 100644 --- a/Makefile.umbrella.tmk +++ b/Makefile.umbrella.tmk @@ -77,6 +77,7 @@ NV_REPOSITORY_COMPONENTS += userspace/units/gr/config NV_REPOSITORY_COMPONENTS += userspace/units/gr/init NV_REPOSITORY_COMPONENTS += userspace/units/gr/intr NV_REPOSITORY_COMPONENTS += userspace/units/acr +NV_REPOSITORY_COMPONENTS += userspace/units/cg endif # Local Variables: diff --git a/drivers/gpu/nvgpu/libnvgpu-drv_safe.export b/drivers/gpu/nvgpu/libnvgpu-drv_safe.export index 00c349116..4fd66a0e1 100644 --- a/drivers/gpu/nvgpu/libnvgpu-drv_safe.export +++ b/drivers/gpu/nvgpu/libnvgpu-drv_safe.export @@ -38,6 +38,50 @@ gv11b_mm_l2_flush gv11b_mm_mmu_fault_disable_hw gv11b_mm_mmu_fault_info_mem_destroy gv11b_mc_is_mmu_fault_pending +gv11b_slcg_bus_gating_prod_size +gv11b_slcg_bus_get_gating_prod +gv11b_slcg_ce2_gating_prod_size +gv11b_slcg_ce2_get_gating_prod +gv11b_slcg_chiplet_gating_prod_size +gv11b_slcg_chiplet_get_gating_prod +gv11b_slcg_fb_gating_prod_size +gv11b_slcg_fb_get_gating_prod +gv11b_slcg_fifo_gating_prod_size +gv11b_slcg_fifo_get_gating_prod +gv11b_slcg_gr_gating_prod_size +gv11b_slcg_gr_get_gating_prod +gv11b_slcg_ltc_gating_prod_size +gv11b_slcg_ltc_get_gating_prod +gv11b_slcg_perf_gating_prod_size +gv11b_slcg_perf_get_gating_prod +gv11b_slcg_priring_gating_prod_size +gv11b_slcg_priring_get_gating_prod +gv11b_slcg_pmu_gating_prod_size +gv11b_slcg_pmu_get_gating_prod +gv11b_slcg_xbar_gating_prod_size +gv11b_slcg_xbar_get_gating_prod +gv11b_slcg_hshub_gating_prod_size +gv11b_slcg_hshub_get_gating_prod +gv11b_blcg_bus_gating_prod_size +gv11b_blcg_bus_get_gating_prod +gv11b_blcg_ce_gating_prod_size +gv11b_blcg_ce_get_gating_prod +gv11b_blcg_ctxsw_firmware_gating_prod_size +gv11b_blcg_ctxsw_firmware_get_gating_prod +gv11b_blcg_fb_gating_prod_size +gv11b_blcg_fb_get_gating_prod +gv11b_blcg_fifo_gating_prod_size +gv11b_blcg_fifo_get_gating_prod +gv11b_blcg_gr_gating_prod_size +gv11b_blcg_gr_get_gating_prod +gv11b_blcg_ltc_gating_prod_size +gv11b_blcg_ltc_get_gating_prod +gv11b_blcg_pmu_gating_prod_size +gv11b_blcg_pmu_get_gating_prod +gv11b_blcg_xbar_gating_prod_size +gv11b_blcg_xbar_get_gating_prod +gv11b_blcg_hshub_gating_prod_size +gv11b_blcg_hshub_get_gating_prod nvgpu_acr_init nvgpu_alloc nvgpu_alloc_base @@ -59,6 +103,17 @@ nvgpu_bar1_writel nvgpu_bitmap_clear nvgpu_bitmap_set nvgpu_bsearch +nvgpu_cg_blcg_fb_ltc_load_enable +nvgpu_cg_blcg_fifo_load_enable +nvgpu_cg_blcg_pmu_load_enable +nvgpu_cg_blcg_ce_load_enable +nvgpu_cg_blcg_gr_load_enable +nvgpu_cg_slcg_fb_ltc_load_enable +nvgpu_cg_slcg_priring_load_enable +nvgpu_cg_slcg_fifo_load_enable +nvgpu_cg_slcg_pmu_load_enable +nvgpu_cg_slcg_ce2_load_enable +nvgpu_cg_init_gr_load_gating_prod nvgpu_gr_alloc nvgpu_gr_free nvgpu_gr_init diff --git a/userspace/Makefile.sources b/userspace/Makefile.sources index 537299c60..f81f8e0e0 100644 --- a/userspace/Makefile.sources +++ b/userspace/Makefile.sources @@ -83,5 +83,6 @@ UNITS := \ $(UNIT_SRC)/gr/falcon \ $(UNIT_SRC)/gr/config \ $(UNIT_SRC)/gr/init \ - $(UNIT_SRC)/gr/intr \ - $(UNIT_SRC)/acr + $(UNIT_SRC)/gr/intr \ + $(UNIT_SRC)/acr \ + $(UNIT_SRC)/cg diff --git a/userspace/SWUTS.h b/userspace/SWUTS.h index 100ca081f..3f7e6521f 100644 --- a/userspace/SWUTS.h +++ b/userspace/SWUTS.h @@ -51,6 +51,7 @@ * - @ref SWUTS-posix-timers * - @ref SWUTS-sdl * - @ref SWUTS-acr + * - @ref SWUTS-cg * */ diff --git a/userspace/SWUTS.sources b/userspace/SWUTS.sources index aa3f3377d..8bc4a797c 100644 --- a/userspace/SWUTS.sources +++ b/userspace/SWUTS.sources @@ -1,4 +1,5 @@ INPUT += ../../../userspace/SWUTS.h +INPUT += ../../../userspace/units/cg/nvgpu-cg.h INPUT += ../../../userspace/units/enabled/nvgpu-enabled.h INPUT += ../../../userspace/units/fifo/nvgpu-fifo.h INPUT += ../../../userspace/units/fifo/channel/nvgpu-channel.h diff --git a/userspace/required_tests.json b/userspace/required_tests.json index 07eeb77d3..540d08d59 100644 --- a/userspace/required_tests.json +++ b/userspace/required_tests.json @@ -294,6 +294,71 @@ "test_level": 0, "unit": "buddy_allocator" }, + { + "test": "blcg_ce", + "test_level": 0, + "unit": "cg" + }, + { + "test": "blcg_fb_ltc", + "test_level": 0, + "unit": "cg" + }, + { + "test": "blcg_fifo", + "test_level": 0, + "unit": "cg" + }, + { + "test": "blcg_gr", + "test_level": 0, + "unit": "cg" + }, + { + "test": "blcg_gr_load_gating_prod", + "test_level": 0, + "unit": "cg" + }, + { + "test": "blcg_pmu", + "test_level": 0, + "unit": "cg" + }, + { + "test": "init", + "test_level": 0, + "unit": "cg" + }, + { + "test": "slcg_ce2", + "test_level": 0, + "unit": "cg" + }, + { + "test": "slcg_fb_ltc", + "test_level": 0, + "unit": "cg" + }, + { + "test": "slcg_fifo", + "test_level": 0, + "unit": "cg" + }, + { + "test": "slcg_gr_load_gating_prod", + "test_level": 0, + "unit": "cg" + }, + { + "test": "slcg_pmu", + "test_level": 0, + "unit": "cg" + }, + { + "test": "slcg_priring", + "test_level": 0, + "unit": "cg" + }, { "test": "enabled_flags_false_check", "test_level": 0, diff --git a/userspace/units/cg/Makefile b/userspace/units/cg/Makefile new file mode 100644 index 000000000..605c41ce5 --- /dev/null +++ b/userspace/units/cg/Makefile @@ -0,0 +1,26 @@ +# Copyright (c) 2019, NVIDIA CORPORATION. All rights reserved. +# +# Permission is hereby granted, free of charge, to any person obtaining a +# copy of this software and associated documentation files (the "Software"), +# to deal in the Software without restriction, including without limitation +# the rights to use, copy, modify, merge, publish, distribute, sublicense, +# and/or sell copies of the Software, and to permit persons to whom the +# Software is furnished to do so, subject to the following conditions: +# +# The above copyright notice and this permission notice shall be included in +# all copies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL +# THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +# FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER +# DEALINGS IN THE SOFTWARE. + +.SUFFIXES: + +OBJS = nvgpu-cg.o +MODULE = nvgpu-cg + +include ../Makefile.units diff --git a/userspace/units/cg/Makefile.interface.tmk b/userspace/units/cg/Makefile.interface.tmk new file mode 100644 index 000000000..44d1d8a9a --- /dev/null +++ b/userspace/units/cg/Makefile.interface.tmk @@ -0,0 +1,34 @@ +################################### tell Emacs this is a -*- makefile-gmake -*- +# +# Copyright (c) 2019, NVIDIA CORPORATION. All rights reserved. +# +# Permission is hereby granted, free of charge, to any person obtaining a +# copy of this software and associated documentation files (the "Software"), +# to deal in the Software without restriction, including without limitation +# the rights to use, copy, modify, merge, publish, distribute, sublicense, +# and/or sell copies of the Software, and to permit persons to whom the +# Software is furnished to do so, subject to the following conditions: +# +# The above copyright notice and this permission notice shall be included in +# all copies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL +# THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +# FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER +# DEALINGS IN THE SOFTWARE. +# +# tmake for SW Mobile component makefile +# +############################################################################### + +NVGPU_UNIT_NAME=nvgpu-cg +include $(NV_COMPONENT_DIR)/../Makefile.units.common.interface.tmk + +# Local Variables: +# indent-tabs-mode: t +# tab-width: 8 +# End: +# vi: set tabstop=8 noexpandtab: diff --git a/userspace/units/cg/Makefile.tmk b/userspace/units/cg/Makefile.tmk new file mode 100644 index 000000000..879f92747 --- /dev/null +++ b/userspace/units/cg/Makefile.tmk @@ -0,0 +1,36 @@ +################################### tell Emacs this is a -*- makefile-gmake -*- +# +# Copyright (c) 2019, NVIDIA CORPORATION. All rights reserved. +# +# Permission is hereby granted, free of charge, to any person obtaining a +# copy of this software and associated documentation files (the "Software"), +# to deal in the Software without restriction, including without limitation +# the rights to use, copy, modify, merge, publish, distribute, sublicense, +# and/or sell copies of the Software, and to permit persons to whom the +# Software is furnished to do so, subject to the following conditions: +# +# The above copyright notice and this permission notice shall be included in +# all copies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL +# THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +# FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER +# DEALINGS IN THE SOFTWARE. +# +# tmake for SW Mobile component makefile +# +############################################################################### + +NVGPU_UNIT_NAME=nvgpu-cg +NVGPU_UNIT_SRCS=nvgpu-cg.c + +include $(NV_COMPONENT_DIR)/../Makefile.units.common.tmk + +# Local Variables: +# indent-tabs-mode: t +# tab-width: 8 +# End: +# vi: set tabstop=8 noexpandtab: diff --git a/userspace/units/cg/nvgpu-cg.c b/userspace/units/cg/nvgpu-cg.c new file mode 100644 index 000000000..d39052486 --- /dev/null +++ b/userspace/units/cg/nvgpu-cg.c @@ -0,0 +1,445 @@ +/* + * Copyright (c) 2019, NVIDIA CORPORATION. All rights reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + * DEALINGS IN THE SOFTWARE. + */ + +#include +#include + +#include +#include +#include +#include +#include +#include + +#include "hal/init/hal_gv11b.h" +#include "hal/power_features/cg/gating_reglist.h" +#include "hal/power_features/cg/gv11b_gating_reglist.h" + +#include "nvgpu-cg.h" + +struct cg_test_data { + u32 cg_type; + void (*load_enable)(struct gk20a *g); + u32 domain_count; + const struct gating_desc *domain_descs[16]; + u32 domain_desc_sizes[16]; +}; + +static struct cg_test_data blcg_fb_ltc = { + .cg_type = NVGPU_GPU_CAN_BLCG, + .load_enable = nvgpu_cg_blcg_fb_ltc_load_enable, + .domain_count = 2, +}; + +static struct cg_test_data blcg_fifo = { + .cg_type = NVGPU_GPU_CAN_BLCG, + .load_enable = nvgpu_cg_blcg_fifo_load_enable, + .domain_count = 1, +}; + +static struct cg_test_data blcg_pmu = { + .cg_type = NVGPU_GPU_CAN_BLCG, + .load_enable = nvgpu_cg_blcg_pmu_load_enable, + .domain_count = 1, +}; + +static struct cg_test_data blcg_ce = { + .cg_type = NVGPU_GPU_CAN_BLCG, + .load_enable = nvgpu_cg_blcg_ce_load_enable, + .domain_count = 1, +}; + +static struct cg_test_data blcg_gr = { + .cg_type = NVGPU_GPU_CAN_BLCG, + .load_enable = nvgpu_cg_blcg_gr_load_enable, + .domain_count = 1, +}; + +static struct cg_test_data slcg_fb_ltc = { + .cg_type = NVGPU_GPU_CAN_SLCG, + .load_enable = nvgpu_cg_slcg_fb_ltc_load_enable, + .domain_count = 2, +}; + +static struct cg_test_data slcg_priring = { + .cg_type = NVGPU_GPU_CAN_SLCG, + .load_enable = nvgpu_cg_slcg_priring_load_enable, + .domain_count = 1, +}; + +static struct cg_test_data slcg_fifo = { + .cg_type = NVGPU_GPU_CAN_SLCG, + .load_enable = nvgpu_cg_slcg_fifo_load_enable, + .domain_count = 1, +}; + +struct cg_test_data slcg_pmu = { + .cg_type = NVGPU_GPU_CAN_SLCG, + .load_enable = nvgpu_cg_slcg_pmu_load_enable, + .domain_count = 1, +}; + +struct cg_test_data slcg_ce2 = { + .cg_type = NVGPU_GPU_CAN_SLCG, + .load_enable = nvgpu_cg_slcg_ce2_load_enable, + .domain_count = 1, +}; + +struct cg_test_data slcg_gr_load_gating_prod = { + .cg_type = NVGPU_GPU_CAN_SLCG, + .load_enable = nvgpu_cg_init_gr_load_gating_prod, + .domain_count = 6, +}; + +struct cg_test_data blcg_gr_load_gating_prod = { + .cg_type = NVGPU_GPU_CAN_BLCG, + .load_enable = nvgpu_cg_init_gr_load_gating_prod, + .domain_count = 4, +}; + +#define INIT_BLCG_DOMAIN_TEST_DATA(param) ({\ + struct cg_test_data *tmp = &blcg_##param; \ + tmp->domain_descs[0] = gv11b_blcg_##param##_get_gating_prod(); \ + tmp->domain_desc_sizes[0] = gv11b_blcg_##param##_gating_prod_size(); \ + }) + +static void init_blcg_fb_ltc_data(void) +{ + blcg_fb_ltc.domain_descs[0] = gv11b_blcg_fb_get_gating_prod(); + blcg_fb_ltc.domain_desc_sizes[0] = gv11b_blcg_fb_gating_prod_size(); + blcg_fb_ltc.domain_descs[1] = gv11b_blcg_ltc_get_gating_prod(); + blcg_fb_ltc.domain_desc_sizes[1] = gv11b_blcg_ltc_gating_prod_size(); +} + +static void init_blcg_fifo_data(void) +{ + INIT_BLCG_DOMAIN_TEST_DATA(fifo); +} + +static void init_blcg_pmu_data(void) +{ + INIT_BLCG_DOMAIN_TEST_DATA(pmu); +} + +static void init_blcg_ce_data(void) +{ + INIT_BLCG_DOMAIN_TEST_DATA(ce); +} + +static void init_blcg_gr_data(void) +{ + INIT_BLCG_DOMAIN_TEST_DATA(gr); +} + +static void init_blcg_gr_load_gating_data(void) +{ + blcg_gr_load_gating_prod.domain_descs[0] = + gv11b_blcg_bus_get_gating_prod(); + blcg_gr_load_gating_prod.domain_desc_sizes[0] = + gv11b_blcg_bus_gating_prod_size(); + blcg_gr_load_gating_prod.domain_descs[1] = + gv11b_blcg_gr_get_gating_prod(); + blcg_gr_load_gating_prod.domain_desc_sizes[1] = + gv11b_blcg_gr_gating_prod_size(); + blcg_gr_load_gating_prod.domain_descs[2] = + gv11b_blcg_xbar_get_gating_prod(); + blcg_gr_load_gating_prod.domain_desc_sizes[2] = + gv11b_blcg_xbar_gating_prod_size(); + blcg_gr_load_gating_prod.domain_descs[3] = + gv11b_blcg_hshub_get_gating_prod(); + blcg_gr_load_gating_prod.domain_desc_sizes[3] = + gv11b_blcg_hshub_gating_prod_size(); +} + +#define INIT_SLCG_DOMAIN_TEST_DATA(param) ({\ + struct cg_test_data *tmp = &slcg_##param; \ + tmp->domain_descs[0] = gv11b_slcg_##param##_get_gating_prod(); \ + tmp->domain_desc_sizes[0] = gv11b_slcg_##param##_gating_prod_size(); \ + }) + +static void init_slcg_fb_ltc_data(void) +{ + slcg_fb_ltc.domain_descs[0] = gv11b_slcg_fb_get_gating_prod(); + slcg_fb_ltc.domain_desc_sizes[0] = gv11b_slcg_fb_gating_prod_size(); + slcg_fb_ltc.domain_descs[1] = gv11b_slcg_ltc_get_gating_prod(); + slcg_fb_ltc.domain_desc_sizes[1] = gv11b_slcg_ltc_gating_prod_size(); +} + +static void init_slcg_priring_data(void) +{ + INIT_SLCG_DOMAIN_TEST_DATA(priring); +} + +static void init_slcg_fifo_data(void) +{ + INIT_SLCG_DOMAIN_TEST_DATA(fifo); +} + +static void init_slcg_pmu_data(void) +{ + INIT_SLCG_DOMAIN_TEST_DATA(pmu); +} + +static void init_slcg_ce2_data(void) +{ + INIT_SLCG_DOMAIN_TEST_DATA(ce2); +} + +static void init_slcg_gr_load_gating_data(void) +{ + slcg_gr_load_gating_prod.domain_descs[0] = + gv11b_slcg_bus_get_gating_prod(); + slcg_gr_load_gating_prod.domain_desc_sizes[0] = + gv11b_slcg_bus_gating_prod_size(); + slcg_gr_load_gating_prod.domain_descs[1] = + gv11b_slcg_chiplet_get_gating_prod(); + slcg_gr_load_gating_prod.domain_desc_sizes[1] = + gv11b_slcg_chiplet_gating_prod_size(); + slcg_gr_load_gating_prod.domain_descs[2] = + gv11b_slcg_gr_get_gating_prod(); + slcg_gr_load_gating_prod.domain_desc_sizes[2] = + gv11b_slcg_gr_gating_prod_size(); + slcg_gr_load_gating_prod.domain_descs[3] = + gv11b_slcg_perf_get_gating_prod(); + slcg_gr_load_gating_prod.domain_desc_sizes[3] = + gv11b_slcg_perf_gating_prod_size(); + slcg_gr_load_gating_prod.domain_descs[4] = + gv11b_slcg_xbar_get_gating_prod(); + slcg_gr_load_gating_prod.domain_desc_sizes[4] = + gv11b_slcg_xbar_gating_prod_size(); + slcg_gr_load_gating_prod.domain_descs[5] = + gv11b_slcg_hshub_get_gating_prod(); + slcg_gr_load_gating_prod.domain_desc_sizes[5] = + gv11b_slcg_hshub_gating_prod_size(); +} + +static void writel_access_reg_fn(struct gk20a *g, + struct nvgpu_reg_access *access) +{ + nvgpu_posix_io_writel_reg_space(g, access->addr, access->value); + nvgpu_posix_io_record_access(g, access); +} + +static void readl_access_reg_fn(struct gk20a *g, + struct nvgpu_reg_access *access) +{ + access->value = nvgpu_posix_io_readl_reg_space(g, access->addr); +} + + +static struct nvgpu_posix_io_callbacks cg_callbacks = { + /* Write APIs all can use the same accessor. */ + .writel = writel_access_reg_fn, + .writel_check = writel_access_reg_fn, + .bar1_writel = writel_access_reg_fn, + .usermode_writel = writel_access_reg_fn, + + /* Likewise for the read APIs. */ + .__readl = readl_access_reg_fn, + .readl = readl_access_reg_fn, + .bar1_readl = readl_access_reg_fn, +}; + +static int init_test_env(struct unit_module *m, struct gk20a *g, void *args) +{ + nvgpu_posix_register_io(g, &cg_callbacks); + nvgpu_posix_io_init_reg_space(g); + + /* + * Fuse register fuse_opt_priv_sec_en_r() is read during init_hal hence + * add it to reg space + */ + if (nvgpu_posix_io_add_reg_space(g, + fuse_opt_priv_sec_en_r(), 0x4) != 0) { + unit_err(m, "Add reg space failed!\n"); + return UNIT_FAIL; + } + + gv11b_init_hal(g); + + init_blcg_fb_ltc_data(); + init_blcg_fifo_data(); + init_blcg_pmu_data(); + init_blcg_ce_data(); + init_blcg_gr_data(); + init_blcg_gr_load_gating_data(); + + init_slcg_fb_ltc_data(); + init_slcg_priring_data(); + init_slcg_fifo_data(); + init_slcg_pmu_data(); + init_slcg_ce2_data(); + init_slcg_gr_load_gating_data(); + + return UNIT_SUCCESS; +} + +static int add_domain_gating_regs(struct gk20a *g, + const struct gating_desc *desc, u32 size) +{ + int err = 0; + u32 i, j; + + for (i = 0; i < size; i++) { + if (nvgpu_posix_io_add_reg_space(g, desc[i].addr, 0x4) != 0) { + err = -ENOMEM; + goto clean_regs; + } + } + + return 0; + +clean_regs: + + for (j = 0; j < i; j++) { + nvgpu_posix_io_delete_reg_space(g, desc[j].addr); + } + + return err; +} + +static void delete_domain_gating_regs(struct gk20a *g, + const struct gating_desc *desc, u32 size) +{ + u32 i; + + for (i = 0; i < size; i++) { + nvgpu_posix_io_delete_reg_space(g, desc[i].addr); + } +} + +static void invalid_load_enabled(struct gk20a *g, + struct cg_test_data *test_data) +{ + u32 i, j; + + for (i = 0; i < test_data->domain_count; i++) { + for (j = 0; j < test_data->domain_desc_sizes[i]; j++) { + nvgpu_writel(g, test_data->domain_descs[i][j].addr, + 0xdeadbeed); + } + } +} + +static int verify_load_enabled(struct gk20a *g, struct cg_test_data *test_data) +{ + u32 i, j, value; + int mismatch = 0; + + for (i = 0; i < test_data->domain_count; i++) { + for (j = 0; j < test_data->domain_desc_sizes[i]; j++) { + value = + nvgpu_readl(g, test_data->domain_descs[i][j].addr); + if (value != test_data->domain_descs[i][j].prod) { + mismatch = 1; + goto out; + } + } + } + +out: + return mismatch; +} + +int test_cg(struct unit_module *m, struct gk20a *g, void *args) +{ + struct cg_test_data *test_data = (struct cg_test_data *) args; + u32 i; + int err; + + for (i = 0; i < test_data->domain_count; i++) { + err = add_domain_gating_regs(g, test_data->domain_descs[i], + test_data->domain_desc_sizes[i]); + if (err != 0) { + return UNIT_FAIL; + } + } + + invalid_load_enabled(g, test_data); + + test_data->load_enable(g); + err = verify_load_enabled(g, test_data); + if (err == 0) { + unit_err(m, "enabled flag not yet set\n"); + return UNIT_FAIL; + } + + nvgpu_set_enabled(g, test_data->cg_type, true); + test_data->load_enable(g); + err = verify_load_enabled(g, test_data); + if (err == 0) { + unit_err(m, "platform capability not yet set\n"); + return UNIT_FAIL; + } + + if (test_data->cg_type == NVGPU_GPU_CAN_BLCG) { + g->blcg_enabled = true; + } else if (test_data->cg_type == NVGPU_GPU_CAN_SLCG) { + g->slcg_enabled = true; + } + test_data->load_enable(g); + err = verify_load_enabled(g, test_data); + if (err != 0) { + unit_err(m, "gating registers mismatch\n"); + return UNIT_FAIL; + } + + for (i = 0; i < test_data->domain_count; i++) { + delete_domain_gating_regs(g, test_data->domain_descs[i], + test_data->domain_desc_sizes[i]); + } + + nvgpu_set_enabled(g, test_data->cg_type, false); + + g->blcg_enabled = false; + g->slcg_enabled = false; + + /* Check that no invalid register access occurred */ + if (nvgpu_posix_io_get_error_code(g) != 0) { + unit_return_fail(m, "Invalid register accessed\n"); + } + + return UNIT_SUCCESS; +} + +struct unit_module_test cg_tests[] = { + UNIT_TEST(init, init_test_env, NULL, 0), + + UNIT_TEST(blcg_fb_ltc, test_cg, &blcg_fb_ltc, 0), + UNIT_TEST(blcg_fifo, test_cg, &blcg_fifo, 0), + UNIT_TEST(blcg_ce, test_cg, &blcg_ce, 0), + UNIT_TEST(blcg_pmu, test_cg, &blcg_pmu, 0), + UNIT_TEST(blcg_gr, test_cg, &blcg_gr, 0), + + UNIT_TEST(slcg_fb_ltc, test_cg, &slcg_fb_ltc, 0), + UNIT_TEST(slcg_priring, test_cg, &slcg_priring, 0), + UNIT_TEST(slcg_fifo, test_cg, &slcg_fifo, 0), + UNIT_TEST(slcg_pmu, test_cg, &slcg_pmu, 0), + UNIT_TEST(slcg_ce2, test_cg, &slcg_ce2, 0), + + UNIT_TEST(slcg_gr_load_gating_prod, test_cg, + &slcg_gr_load_gating_prod, 0), + UNIT_TEST(blcg_gr_load_gating_prod, test_cg, + &blcg_gr_load_gating_prod, 0), +}; + +UNIT_MODULE(cg, cg_tests, UNIT_PRIO_NVGPU_TEST); diff --git a/userspace/units/cg/nvgpu-cg.h b/userspace/units/cg/nvgpu-cg.h new file mode 100644 index 000000000..285813d2c --- /dev/null +++ b/userspace/units/cg/nvgpu-cg.h @@ -0,0 +1,67 @@ +/* + * Copyright (c) 2019, NVIDIA CORPORATION. All rights reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + * DEALINGS IN THE SOFTWARE. + */ + +struct gk20a; +struct unit_module; + +/** @addtogroup SWUTS-cg + * @{ + * + * Software Unit Test Specification for cg + */ + +/** + * Test specification for: test_cg + * + * Description: The cg unit shall be able to setup the clock gating register + * values as specified in the hal reglist structures for BLCG/SLCG. + * + * Test Type: Feature based + * + * Input: The struct specifying type of clock gating, target nvgpu routine + * that handles the setup, clock gating domain descriptors. + * + * Steps: + * - Initialize the test environment: + * - Register read/write IO callbacks. + * - Add relevant fuse registers to the register space. + * - Initialize hal to setup the hal functions. + * - Initialize slcg and blcg gating register data by querying through + * nvgpu exported functions. + * - Add the domain gating registers to the register space. + * - Load invalid values in the gating registers. + * - Invoke the nvgpu function to load the clock gating values. + * - Verify that load is not enabled as BLCG/SLCG enabled flag isn't set. + * - Enable BLCG/SLCG enabled flag. + * - Invoke the nvgpu function to load the clock gating values. + * - Verify that load is not enabled as platform capability isn't set. + * - Set the platform capability. + * - Invoke the nvgpu function to load the clock gating values. + * - Verify that load is enabled. + * - Any invalid accesses by nvgpu will be caught through ABORTs and + * test fails if ABORTs are encountered. + * - Delete domain gating registers from the registere space. + * + * Output: Returns PASS if the steps above were executed successfully. FAIL + * otherwise. + */ +int test_cg(struct unit_module *m, struct gk20a *g, void *args);