diff --git a/Makefile.umbrella.tmk b/Makefile.umbrella.tmk index 737ebc262..1f563dcae 100644 --- a/Makefile.umbrella.tmk +++ b/Makefile.umbrella.tmk @@ -79,6 +79,7 @@ NV_REPOSITORY_COMPONENTS += userspace/units/fifo/engine/gm20b NV_REPOSITORY_COMPONENTS += userspace/units/fifo/engine/gp10b NV_REPOSITORY_COMPONENTS += userspace/units/fifo/engine/gv100 NV_REPOSITORY_COMPONENTS += userspace/units/fifo/engine/gv11b +NV_REPOSITORY_COMPONENTS += userspace/units/fifo/fifo/gk20a NV_REPOSITORY_COMPONENTS += userspace/units/fifo/pbdma NV_REPOSITORY_COMPONENTS += userspace/units/fifo/pbdma/gv11b NV_REPOSITORY_COMPONENTS += userspace/units/fifo/pbdma/gm20b diff --git a/drivers/gpu/nvgpu/libnvgpu-drv_safe.export b/drivers/gpu/nvgpu/libnvgpu-drv_safe.export index f0af38295..8fd50d2b0 100644 --- a/drivers/gpu/nvgpu/libnvgpu-drv_safe.export +++ b/drivers/gpu/nvgpu/libnvgpu-drv_safe.export @@ -15,6 +15,14 @@ gk20a_as_release_share gk20a_channel_disable gk20a_channel_enable gk20a_channel_read_state +gk20a_fifo_get_pb_timeslice +gk20a_fifo_get_runlist_timeslice +gk20a_fifo_init_pbdma_map +gk20a_fifo_intr_1_enable +gk20a_fifo_intr_1_isr +gk20a_fifo_intr_handle_chsw_error +gk20a_fifo_intr_handle_runlist_event +gk20a_fifo_pbdma_isr gk20a_mm_fb_flush gk20a_ptimer_isr gk20a_ramin_alloc_size diff --git a/userspace/Makefile.sources b/userspace/Makefile.sources index 3feaf8d5a..7c785065f 100644 --- a/userspace/Makefile.sources +++ b/userspace/Makefile.sources @@ -78,6 +78,7 @@ UNITS := \ $(UNIT_SRC)/netlist \ $(UNIT_SRC)/fbp \ $(UNIT_SRC)/fifo \ + $(UNIT_SRC)/fifo/fifo/gk20a \ $(UNIT_SRC)/fifo/channel \ $(UNIT_SRC)/fifo/channel/gk20a \ $(UNIT_SRC)/fifo/channel/gm20b \ diff --git a/userspace/SWUTS.h b/userspace/SWUTS.h index 772872d52..d59579a9b 100644 --- a/userspace/SWUTS.h +++ b/userspace/SWUTS.h @@ -46,6 +46,7 @@ * - @ref SWUTS-fifo-engine-gp10b * - @ref SWUTS-fifo-engine-gv100 * - @ref SWUTS-fifo-engine-gv11b + * - @ref SWUTS-fifo-fifo-gk20a * - @ref SWUTS-fifo-pbdma * - @ref SWUTS-fifo-pbdma-gm20b * - @ref SWUTS-fifo-pbdma-gp10b diff --git a/userspace/SWUTS.sources b/userspace/SWUTS.sources index 196c56d0b..716ea943a 100644 --- a/userspace/SWUTS.sources +++ b/userspace/SWUTS.sources @@ -16,6 +16,8 @@ INPUT += ../../../userspace/units/fifo/engine/gm20b/nvgpu-engine-gm20b.h INPUT += ../../../userspace/units/fifo/engine/gp10b/nvgpu-engine-gp10b.h INPUT += ../../../userspace/units/fifo/engine/gv100/nvgpu-engine-gv100.h INPUT += ../../../userspace/units/fifo/engine/gv11b/nvgpu-engine-gv11b.h +INPUT += ../../../userspace/units/fifo/fifo/gk20a/nvgpu-fifo-gk20a.h +INPUT += ../../../userspace/units/fifo/fifo/gk20a/nvgpu-fifo-intr-gk20a.h INPUT += ../../../userspace/units/fifo/pbdma/nvgpu-pbdma.h INPUT += ../../../userspace/units/fifo/pbdma/gm20b/nvgpu-pbdma-gm20b.h INPUT += ../../../userspace/units/fifo/pbdma/gp10b/nvgpu-pbdma-gp10b.h diff --git a/userspace/required_tests.json b/userspace/required_tests.json index fd4e93a4f..2edff6819 100644 --- a/userspace/required_tests.json +++ b/userspace/required_tests.json @@ -1565,6 +1565,60 @@ "unit": "nvgpu_engine_gv11b", "test_level": 0 }, + { + "test": "test_gk20a_get_timeslices", + "case": "get_timeslices", + "unit": "nvgpu_fifo_gk20a", + "test_level": 0 + }, + { + "test": "test_gk20a_init_pbdma_map", + "case": "init_pbdma_map", + "unit": "nvgpu_fifo_gk20a", + "test_level": 0 + }, + { + "test": "test_fifo_init_support", + "case": "init_support", + "unit": "nvgpu_fifo_gk20a", + "test_level": 0 + }, + { + "test": "test_gk20a_fifo_intr_1_enable", + "case": "intr_1_enable", + "unit": "nvgpu_fifo_gk20a", + "test_level": 0 + }, + { + "test": "test_gk20a_fifo_intr_1_isr", + "case": "intr_1_isr", + "unit": "nvgpu_fifo_gk20a", + "test_level": 0 + }, + { + "test": "test_gk20a_fifo_intr_handle_chsw_error", + "case": "intr_handle_chsw_error", + "unit": "nvgpu_fifo_gk20a", + "test_level": 0 + }, + { + "test": "test_gk20a_fifo_intr_handle_runlist_event", + "case": "intr_handle_runlist_event", + "unit": "nvgpu_fifo_gk20a", + "test_level": 0 + }, + { + "test": "test_gk20a_fifo_pbdma_isr", + "case": "pbdma_isr", + "unit": "nvgpu_fifo_gk20a", + "test_level": 0 + }, + { + "test": "test_fifo_remove_support", + "case": "remove_support", + "unit": "nvgpu_fifo_gk20a", + "test_level": 0 + }, { "test": "test_gr_config_count", "case": "config_check_init", diff --git a/userspace/units/fifo/fifo/gk20a/Makefile b/userspace/units/fifo/fifo/gk20a/Makefile new file mode 100644 index 000000000..aa19a310d --- /dev/null +++ b/userspace/units/fifo/fifo/gk20a/Makefile @@ -0,0 +1,32 @@ +# 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-fifo-gk20a.o nvgpu-fifo-intr-gk20a.o +MODULE = nvgpu-fifo-gk20a + +LIB_PATHS += -lnvgpu-fifo +include ../../../Makefile.units + +lib$(MODULE).so: fifo + +fifo: + $(MAKE) -C ../.. diff --git a/userspace/units/fifo/fifo/gk20a/Makefile.interface.tmk b/userspace/units/fifo/fifo/gk20a/Makefile.interface.tmk new file mode 100644 index 000000000..ae873bbe8 --- /dev/null +++ b/userspace/units/fifo/fifo/gk20a/Makefile.interface.tmk @@ -0,0 +1,35 @@ +################################### 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-fifo-gk20a + +include $(NV_SOURCE)/kernel/nvgpu/userspace/units/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/fifo/fifo/gk20a/Makefile.tmk b/userspace/units/fifo/fifo/gk20a/Makefile.tmk new file mode 100644 index 000000000..afbc50099 --- /dev/null +++ b/userspace/units/fifo/fifo/gk20a/Makefile.tmk @@ -0,0 +1,40 @@ +################################### 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-fifo-gk20a +NVGPU_UNIT_SRCS = nvgpu-fifo-gk20a.c nvgpu-fifo-intr-gk20a.c + +NVGPU_UNIT_INTERFACE_DIRS := \ + $(NV_SOURCE)/kernel/nvgpu/userspace/units/fifo \ + $(NV_SOURCE)/kernel/nvgpu/drivers/gpu/nvgpu + +include $(NV_SOURCE)/kernel/nvgpu/userspace/units/Makefile.units.common.tmk + +# Local Variables: +# indent-tabs-mode: t +# tab-width: 8 +# End: +# vi: set tabstop=8 noexpandtab: diff --git a/userspace/units/fifo/fifo/gk20a/nvgpu-fifo-gk20a.c b/userspace/units/fifo/fifo/gk20a/nvgpu-fifo-gk20a.c new file mode 100644 index 000000000..3447211b9 --- /dev/null +++ b/userspace/units/fifo/fifo/gk20a/nvgpu-fifo-gk20a.c @@ -0,0 +1,122 @@ +/* + * 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 +#include +#include +#include +#include + +#include "hal/fifo/fifo_gk20a.h" +#include + +#include "../../nvgpu-fifo.h" +#include "nvgpu-fifo-gk20a.h" +#include "nvgpu-fifo-intr-gk20a.h" + +#define FIFO_GK20A_UNIT_DEBUG +#ifdef FIFO_GK20A_UNIT_DEBUG +#undef unit_verbose +#define unit_verbose unit_info +#else +#define unit_verbose(unit, msg, ...) \ + do { \ + if (0) { \ + unit_info(unit, msg, ##__VA_ARGS__); \ + } \ + } while (0) +#endif + +#define assert(cond) unit_assert(cond, goto done) + +#define UNIT_MAX_PBDMA 32 + +int test_gk20a_init_pbdma_map(struct unit_module *m, + struct gk20a *g, void *args) +{ + int ret = UNIT_FAIL; + u32 num_pbdma = nvgpu_get_litter_value(g, GPU_LIT_HOST_NUM_PBDMA); + u32 pbdma_map[UNIT_MAX_PBDMA]; + u32 id; + assert(num_pbdma > 0); + assert(num_pbdma <= UNIT_MAX_PBDMA); + + memset(pbdma_map, 0, sizeof(pbdma_map)); + gk20a_fifo_init_pbdma_map(g, pbdma_map, num_pbdma); + for (id = 0; id < num_pbdma; id++) { + unit_verbose(m, "id=%u map=%08x\n", id, pbdma_map[id]); + assert(pbdma_map[id] != 0); + } + + ret = UNIT_SUCCESS; +done: + return ret; +} + +int test_gk20a_get_timeslices(struct unit_module *m, + struct gk20a *g, void *args) +{ + int ret = UNIT_FAIL; + u32 rl_timeslice = gk20a_fifo_get_runlist_timeslice(g); + u32 pb_timeslice = gk20a_fifo_get_pb_timeslice(g); + + /* check that timeslices are enabled */ + assert((rl_timeslice & fifo_runlist_timeslice_enable_true_f()) != 0); + assert((pb_timeslice & fifo_pb_timeslice_enable_true_f()) != 0); + + /* check that timeslices are non-zero */ + assert((rl_timeslice & 0xFF) != 0); + assert((pb_timeslice & 0xFF) != 0); + + ret = UNIT_SUCCESS; +done: + return ret; +} + +struct unit_module_test nvgpu_fifo_gk20a_tests[] = { + UNIT_TEST(init_support, test_fifo_init_support, NULL, 0), + + /* fifo gk20a */ + UNIT_TEST(init_pbdma_map, test_gk20a_init_pbdma_map, NULL, 0), + UNIT_TEST(get_timeslices, test_gk20a_get_timeslices, NULL, 0), + + /* fifo intr gk20a */ + UNIT_TEST(intr_1_enable, test_gk20a_fifo_intr_1_enable, NULL, 0), + UNIT_TEST(intr_1_isr, test_gk20a_fifo_intr_1_isr, NULL, 0), + UNIT_TEST(intr_handle_chsw_error, test_gk20a_fifo_intr_handle_chsw_error, NULL, 0), + UNIT_TEST(intr_handle_runlist_event, test_gk20a_fifo_intr_handle_runlist_event, NULL, 0), + UNIT_TEST(pbdma_isr, test_gk20a_fifo_pbdma_isr, NULL, 0), + + UNIT_TEST(remove_support, test_fifo_remove_support, NULL, 0), +}; + +UNIT_MODULE(nvgpu_fifo_gk20a, nvgpu_fifo_gk20a_tests, UNIT_PRIO_NVGPU_TEST); diff --git a/userspace/units/fifo/fifo/gk20a/nvgpu-fifo-gk20a.h b/userspace/units/fifo/fifo/gk20a/nvgpu-fifo-gk20a.h new file mode 100644 index 000000000..b013bebf0 --- /dev/null +++ b/userspace/units/fifo/fifo/gk20a/nvgpu-fifo-gk20a.h @@ -0,0 +1,83 @@ +/* + * 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. + */ +#ifndef UNIT_NVGPU_FIFO_GK20A_H +#define UNIT_NVGPU_FIFO_GK20A_H + +#include + +struct unit_module; +struct gk20a; + +/** @addtogroup SWUTS-fifo-fifo-gk20a + * @{ + * + * Software Unit Test Specification for fifo/fifo/gk20a + */ + +/** + * Test specification for: test_gk20a_init_pbdma_map + * + * Description: Init PBDMA to runlists map + * + * Test Type: Feature based + * + * Targets: gk20a_fifo_init_pbdma_map + * + * Input: test_fifo_init_support() run for this GPU + * + * Steps: + * - Get number of PBDMA with nvgpu_get_litter_value. + * - Call gk20a_fifo_init_pbdma_map using a pre-allocated pbdma_map. + * - Check that pbdma_map[id] is non-zero for all PBDMAs. + * + * Output: Returns PASS if all branches gave expected results. FAIL otherwise. + */ +int test_gk20a_init_pbdma_map(struct unit_module *m, + struct gk20a *g, void *args); + + +/** + * Test specification for: test_gk20a_get_timeslices + * + * Description: Init PBDMA to runlists map + * + * Test Type: Feature based + * + * Targets: gk20a_fifo_get_runlist_timeslice, gk20a_fifo_get_pb_timeslice + * + * Input: test_fifo_init_support() run for this GPU + * + * Steps: + * - Get runlist timeslice using gk20a_fifo_get_runlist_timeslice. + * - Get PBDMA timeslice using gk20a_fifo_get_pb_timeslice. + * - Check that timeslices are enabled, and non-zero. + * + * Output: Returns PASS if all branches gave expected results. FAIL otherwise. + */ +int test_gk20a_get_timeslices(struct unit_module *m, + struct gk20a *g, void *args); + +/** + * @} + */ + +#endif /* UNIT_NVGPU_FIFO_GK20A_H */ diff --git a/userspace/units/fifo/fifo/gk20a/nvgpu-fifo-intr-gk20a.c b/userspace/units/fifo/fifo/gk20a/nvgpu-fifo-intr-gk20a.c new file mode 100644 index 000000000..4e02ce6f5 --- /dev/null +++ b/userspace/units/fifo/fifo/gk20a/nvgpu-fifo-intr-gk20a.c @@ -0,0 +1,218 @@ +/* + * 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 +#include +#include +#include +#include +#include +#include + +#include "hal/fifo/fifo_intr_gk20a.h" +#include + +#include "../../nvgpu-fifo.h" +#include "nvgpu-fifo-intr-gk20a.h" + +#ifdef FIFO_GK20A_INTR_UNIT_DEBUG +#undef unit_verbose +#define unit_verbose unit_info +#else +#define unit_verbose(unit, msg, ...) \ + do { \ + if (0) { \ + unit_info(unit, msg, ##__VA_ARGS__); \ + } \ + } while (0) +#endif + +#define assert(cond) unit_assert(cond, goto done) + +struct unit_ctx { + u32 count; + bool fail; + bool recover; +}; + +static struct unit_ctx u; + +int test_gk20a_fifo_intr_1_enable(struct unit_module *m, + struct gk20a *g, void *args) +{ + int ret = UNIT_FAIL; + + nvgpu_writel(g, fifo_intr_en_1_r(), 0); + gk20a_fifo_intr_1_enable(g, true); + assert((nvgpu_readl(g, fifo_intr_en_1_r()) & + fifo_intr_0_channel_intr_pending_f()) != 0); + + gk20a_fifo_intr_1_enable(g, false); + assert((nvgpu_readl(g, fifo_intr_en_1_r()) & + fifo_intr_0_channel_intr_pending_f()) == 0); + + assert(ret == UNIT_FAIL); + ret = UNIT_SUCCESS; +done: + return ret; +} + +int test_gk20a_fifo_intr_1_isr(struct unit_module *m, + struct gk20a *g, void *args) +{ + int ret = UNIT_FAIL; + + /* no channel intr pending */ + nvgpu_writel(g, fifo_intr_0_r(), ~fifo_intr_0_channel_intr_pending_f()); + gk20a_fifo_intr_1_isr(g); + assert(nvgpu_readl(g, fifo_intr_0_r()) == 0); + + /* channel intr pending */ + nvgpu_writel(g, fifo_intr_0_r(), U32_MAX); + gk20a_fifo_intr_1_isr(g); + assert(nvgpu_readl(g, fifo_intr_0_r()) == fifo_intr_0_channel_intr_pending_f()); + + ret = UNIT_SUCCESS; +done: + return ret; +} + +static void stub_gr_falcon_dump_stats(struct gk20a *g) +{ + nvgpu_writel(g, fifo_intr_chsw_error_r(), 0); + u.count++; +} + +int test_gk20a_fifo_intr_handle_chsw_error(struct unit_module *m, + struct gk20a *g, void *args) +{ + int ret = UNIT_FAIL; + struct gpu_ops gops = g->ops; + + g->ops.gr.falcon.dump_stats = stub_gr_falcon_dump_stats; + + u.count = 0; + nvgpu_writel(g, fifo_intr_chsw_error_r(), 0xcafe); + gk20a_fifo_intr_handle_chsw_error(g); + assert(u.count > 0); + assert(nvgpu_readl(g, fifo_intr_chsw_error_r()) == 0xcafe); + + ret = UNIT_SUCCESS; +done: + g->ops = gops; + return ret; +} + + +static void writel_access_reg_fn(struct gk20a *g, + struct nvgpu_reg_access *access) +{ + u.fail = (access->addr != fifo_intr_runlist_r()) || + (access->value != 0xcafe); +} + +static void readl_access_reg_fn(struct gk20a *g, + struct nvgpu_reg_access *access) +{ + if (access->addr == fifo_intr_runlist_r()) { + access->value = 0xcafe; + } else { + u.fail = true; + } +} + +int test_gk20a_fifo_intr_handle_runlist_event(struct unit_module *m, + struct gk20a *g, void *args) +{ + int ret = UNIT_FAIL; + struct nvgpu_posix_io_callbacks *old_io; + struct nvgpu_posix_io_callbacks new_io = { + .readl = readl_access_reg_fn, + .writel = writel_access_reg_fn + }; + + u.fail = false; + old_io = nvgpu_posix_register_io(g, &new_io); + gk20a_fifo_intr_handle_runlist_event(g); + assert(!u.fail); + + ret = UNIT_SUCCESS; +done: + (void) nvgpu_posix_register_io(g, old_io); + return ret; +} + +static bool stub_pbdma_handle_intr(struct gk20a *g, u32 pbdma_id, + u32 *error_notifier, struct nvgpu_pbdma_status_info *pbdma_status) +{ + if (nvgpu_readl(g, fifo_intr_pbdma_id_r()) != BIT(pbdma_id)) { + u.fail = true; + } + + pbdma_status->chsw_status = NVGPU_PBDMA_CHSW_STATUS_INVALID; + u.count++; + + return u.recover; +} + +int test_gk20a_fifo_pbdma_isr(struct unit_module *m, + struct gk20a *g, void *args) +{ + int ret = UNIT_FAIL; + u32 pending; + int i; + u32 pbdma_id; + u32 num_pbdma = nvgpu_get_litter_value(g, GPU_LIT_HOST_NUM_PBDMA); + struct gpu_ops gops = g->ops; + + assert(num_pbdma > 0); + + g->ops.pbdma.handle_intr = stub_pbdma_handle_intr; + + u.fail = false; + for (i = 0; i < 2; i++) { + u.recover = (i > 0); + for (pbdma_id = 0; pbdma_id < num_pbdma; pbdma_id++) { + nvgpu_writel(g, fifo_intr_pbdma_id_r(), BIT(pbdma_id)); + u.count = 0; + pending = gk20a_fifo_pbdma_isr(g); + assert(pending == fifo_intr_0_pbdma_intr_pending_f()); + assert(!u.fail); + assert(u.count == 1); + } + } + ret = UNIT_SUCCESS; + +done: + g->ops = gops; + return ret; +} \ No newline at end of file diff --git a/userspace/units/fifo/fifo/gk20a/nvgpu-fifo-intr-gk20a.h b/userspace/units/fifo/fifo/gk20a/nvgpu-fifo-intr-gk20a.h new file mode 100644 index 000000000..fddd13be2 --- /dev/null +++ b/userspace/units/fifo/fifo/gk20a/nvgpu-fifo-intr-gk20a.h @@ -0,0 +1,160 @@ +/* + * 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. + */ +#ifndef UNIT_NVGPU_FIFO_INTR_GK20A_H +#define UNIT_NVGPU_FIFO_INTR_GK20A_H + +#include + +struct unit_module; +struct gk20a; + +/** @addtogroup SWUTS-fifo-fifo-gk20a + * @{ + * + * Software Unit Test Specification for fifo/fifo/gk20a + */ + +/** + * Test specification for: test_gk20a_fifo_intr_1_enable + * + * Description: Enable/disable non-stalling interrupts + * + * Test Type: Feature based + * + * Targets: gk20a_fifo_intr_1_enable + * + * Input: test_fifo_init_support() run for this GPU + * + * Steps: + * - Clear fifo_intr_en_1_r(). + * - Call gk20a_fifo_intr_1_enable with enable = true, then check that + * interrupts have been enabled in fifo_intr_en_1_r(). + * - Call gk20a_fifo_intr_1_enable with enable = false, then check that + * interrupts have been disabled in fifo_intr_en_1_r(). + * + * Output: Returns PASS if all branches gave expected results. FAIL otherwise. + */ +int test_gk20a_fifo_intr_1_enable(struct unit_module *m, + struct gk20a *g, void *args); + +/** + * Test specification for: test_gk20a_fifo_intr_1_isr + * + * Description: Non-stalling interrupt service routine + * + * Test Type: Feature based + * + * Targets: gk20a_fifo_intr_1_isr + * + * Input: test_fifo_init_support() run for this GPU + * + * Steps: + * - Check that gk20a_fifo_intr_1_isr only clears channel interrupt when + * multiple interrupts are pending. + * - Check that gk20a_fifo_intr_1_isr does not clear any interrupt when + * channel interrupt is not pending. + * + * Output: Returns PASS if all branches gave expected results. FAIL otherwise. + */ +int test_gk20a_fifo_intr_1_isr(struct unit_module *m, + struct gk20a *g, void *args); + +/** + * Test specification for: test_gk20a_fifo_intr_handle_chsw_error + * + * Description: Non-stalling interrupt service routine + * + * Test Type: Feature based + * + * Targets: gk20a_fifo_intr_handle_chsw_error + * + * Input: test_fifo_init_support() run for this GPU + * + * Steps: + * - Write fifo_intr_chsw_error_r to fake some pending interrupts. + * - Call gk20a_fifo_intr_handle_chsw_error. + * - Use stub for gr.falcon.dump to clear fifo_intr_chsw_error_r + * (before the handling function writes back to it, in order to + * clear interrupts). + * - Check that gk20a_fifo_intr_handle_chsw_error clears interrupts + * by writing to fifo_intr_chsw_error_r. + * + * Output: Returns PASS if all branches gave expected results. FAIL otherwise. + */ +int test_gk20a_fifo_intr_handle_chsw_error(struct unit_module *m, + struct gk20a *g, void *args); + +/** + * Test specification for: test_gk20a_fifo_intr_handle_runlist_event + * + * Description: Non-stalling interrupt service routine + * + * Test Type: Feature based + * + * Targets: gk20a_fifo_intr_handle_runlist_event + * + * Input: test_fifo_init_support() run for this GPU + * + * Steps: + * - Install read/write register io callbacks. + * - Call gk20a_fifo_intr_handle_runlist_event. + * - In the read callback, return fake interrupt pending mask. + * - In the write callback, check that the same interrupt mask + * is used to clear interrupts. + * + * Output: Returns PASS if all branches gave expected results. FAIL otherwise. + */ +int test_gk20a_fifo_intr_handle_runlist_event(struct unit_module *m, + struct gk20a *g, void *args); + +/** + * Test specification for: test_gk20a_fifo_pbdma_isr + * + * Description: PBDMA interrupt service routine + * + * Test Type: Feature based + * + * Targets: gk20a_fifo_pbdma_isr + * + * Input: test_fifo_init_support() run for this GPU + * + * Steps: + * - Get number of PBDMAs with nvgpu_get_litter_value, and check that + * it is non-zero. + * - For each pbdma_id: + * - Set bit in fifo_intr_pbdma_id_r to indicate that one + * interrupt is pending for this PBDMA. + * - Call gk20a_fifo_pbdma_isr. + * - Check that ops.pbdma.handle_intr is called exactly once. + * - In the ops.pbdma.handle_intr stub, check that pbdma_id matches + * the interrupt mask. + * + * Output: Returns PASS if all branches gave expected results. FAIL otherwise. + */ +int test_gk20a_fifo_pbdma_isr(struct unit_module *m, + struct gk20a *g, void *args); + +/** + * @} + */ + +#endif /* UNIT_NVGPU_FIFO_INTR_GK20A_H */