diff --git a/Makefile.umbrella.tmk b/Makefile.umbrella.tmk index 88165154d..22c586248 100644 --- a/Makefile.umbrella.tmk +++ b/Makefile.umbrella.tmk @@ -49,6 +49,7 @@ NV_REPOSITORY_COMPONENTS += userspace/units/interface/lock NV_REPOSITORY_COMPONENTS += userspace/units/interface/atomic NV_REPOSITORY_COMPONENTS += userspace/units/interface/rbtree NV_REPOSITORY_COMPONENTS += userspace/units/pramin +NV_REPOSITORY_COMPONENTS += userspace/units/ptimer NV_REPOSITORY_COMPONENTS += userspace/units/mm/nvgpu_sgt NV_REPOSITORY_COMPONENTS += userspace/units/mm/nvgpu_mem NV_REPOSITORY_COMPONENTS += userspace/units/mm/allocators/buddy_allocator diff --git a/drivers/gpu/nvgpu/libnvgpu-drv_safe.export b/drivers/gpu/nvgpu/libnvgpu-drv_safe.export index efa31afa0..18a3eff2c 100644 --- a/drivers/gpu/nvgpu/libnvgpu-drv_safe.export +++ b/drivers/gpu/nvgpu/libnvgpu-drv_safe.export @@ -13,8 +13,10 @@ find_next_bit gk20a_as_alloc_share gk20a_as_release_share gk20a_mm_fb_flush +gk20a_ptimer_isr gk20a_ramin_alloc_size gk20a_ramin_base_shift +gk20a_read_ptimer gk20a_vm_release_share gm20b_fb_tlb_invalidate gm20b_mm_get_big_page_sizes diff --git a/userspace/Makefile.sources b/userspace/Makefile.sources index b583c59da..9e041d28e 100644 --- a/userspace/Makefile.sources +++ b/userspace/Makefile.sources @@ -52,6 +52,7 @@ UNITS := \ $(UNIT_SRC)/posix/cond \ $(UNIT_SRC)/posix/timers \ $(UNIT_SRC)/pramin \ + $(UNIT_SRC)/ptimer \ $(UNIT_SRC)/init \ $(UNIT_SRC)/interface/bsearch \ $(UNIT_SRC)/interface/lock \ diff --git a/userspace/SWUTS.h b/userspace/SWUTS.h index ce1a3d3b1..15ee5b3ec 100644 --- a/userspace/SWUTS.h +++ b/userspace/SWUTS.h @@ -58,6 +58,7 @@ * - @ref SWUTS-posix-sizes * - @ref SWUTS-posix-thread * - @ref SWUTS-posix-timers + * - @ref SWUTS-ptimer * - @ref SWUTS-sdl * - @ref SWUTS-acr * - @ref SWUTS-cg diff --git a/userspace/SWUTS.sources b/userspace/SWUTS.sources index 4e2a2bfcd..85f1698c9 100644 --- a/userspace/SWUTS.sources +++ b/userspace/SWUTS.sources @@ -32,5 +32,6 @@ INPUT += ../../../userspace/units/posix/fault-injection/posix-fault-injection-dm INPUT += ../../../userspace/units/posix/sizes/posix-sizes.h INPUT += ../../../userspace/units/posix/thread/posix-thread.h INPUT += ../../../userspace/units/posix/timers/posix-timers.h +INPUT += ../../../userspace/units/ptimer/nvgpu-ptimer.h INPUT += ../../../userspace/units/acr/nvgpu-acr.h INPUT += ../../../userspace/units/gr/nvgpu-gr.h diff --git a/userspace/units/ptimer/Makefile b/userspace/units/ptimer/Makefile new file mode 100644 index 000000000..4c80b1c17 --- /dev/null +++ b/userspace/units/ptimer/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-ptimer.o +MODULE = ptimer + +include ../Makefile.units diff --git a/userspace/units/ptimer/Makefile.interface.tmk b/userspace/units/ptimer/Makefile.interface.tmk new file mode 100644 index 000000000..f7dd6ecc1 --- /dev/null +++ b/userspace/units/ptimer/Makefile.interface.tmk @@ -0,0 +1,23 @@ +################################### tell Emacs this is a -*- makefile-gmake -*- +# +# Copyright (c) 2019, NVIDIA CORPORATION. All Rights Reserved. +# +# NVIDIA CORPORATION and its licensors retain all intellectual property +# and proprietary rights in and to this software, related documentation +# and any modifications thereto. Any use, reproduction, disclosure or +# distribution of this software and related documentation without an express +# license agreement from NVIDIA CORPORATION is strictly prohibited. +# +# tmake for SW Mobile component makefile +# +############################################################################### + +NVGPU_UNIT_NAME=ptimer + +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/ptimer/Makefile.tmk b/userspace/units/ptimer/Makefile.tmk new file mode 100644 index 000000000..e6cacfea9 --- /dev/null +++ b/userspace/units/ptimer/Makefile.tmk @@ -0,0 +1,24 @@ +################################### tell Emacs this is a -*- makefile-gmake -*- +# +# Copyright (c) 2019, NVIDIA CORPORATION. All Rights Reserved. +# +# NVIDIA CORPORATION and its licensors retain all intellectual property +# and proprietary rights in and to this software, related documentation +# and any modifications thereto. Any use, reproduction, disclosure or +# distribution of this software and related documentation without an express +# license agreement from NVIDIA CORPORATION is strictly prohibited. +# +# tmake for SW Mobile component makefile +# +############################################################################### + +NVGPU_UNIT_NAME=ptimer +NVGPU_UNIT_SRCS=nvgpu-ptimer.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/ptimer/nvgpu-ptimer.c b/userspace/units/ptimer/nvgpu-ptimer.c new file mode 100644 index 000000000..8c839d8a8 --- /dev/null +++ b/userspace/units/ptimer/nvgpu-ptimer.c @@ -0,0 +1,322 @@ +/* + * 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 "nvgpu-ptimer.h" + +/* + * Mock I/O + */ + +/* + * Write callback. Forward the write access to the mock IO framework. + */ +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); +} + +/* Used to simulate wrap */ +#define TIMER1_VALUES_SIZE 4 +static u32 timer1_values[TIMER1_VALUES_SIZE]; +static u32 timer1_index; + +/* + * Read callback. Get the register value from the mock IO framework. + */ +static void readl_access_reg_fn(struct gk20a *g, + struct nvgpu_reg_access *access) +{ + /* Used to simulate wrap */ + if (access->addr == timer_time_1_r()) { + BUG_ON(timer1_index >= TIMER1_VALUES_SIZE); + access->value = timer1_values[timer1_index++]; + } else { + access->value = nvgpu_posix_io_readl_reg_space(g, access->addr); + } +} + +static struct nvgpu_posix_io_callbacks test_reg_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, +}; + +/* map the whole page */ +#define PTIMER_REG_SPACE_START (timer_pri_timeout_r() & ~0xfff) +#define PTIMER_REG_SPACE_SIZE 0xfff + +int test_setup_env(struct unit_module *m, + struct gk20a *g, void *args) +{ + /* Setup HAL */ + g->ops.ptimer.read_ptimer = gk20a_read_ptimer; + g->ops.ptimer.isr = gk20a_ptimer_isr; + + /* Create ptimer register space */ + nvgpu_posix_io_init_reg_space(g); + if (nvgpu_posix_io_add_reg_space(g, PTIMER_REG_SPACE_START, + PTIMER_REG_SPACE_SIZE) != 0) { + unit_err(m, "%s: failed to create register space\n", + __func__); + return UNIT_FAIL; + } + (void)nvgpu_posix_register_io(g, &test_reg_callbacks); + + return UNIT_SUCCESS; +} + +int test_free_env(struct unit_module *m, + struct gk20a *g, void *args) +{ + /* Free register space */ + nvgpu_posix_io_delete_reg_space(g, PTIMER_REG_SPACE_START); + + return UNIT_SUCCESS; +} + +int test_read_ptimer(struct unit_module *m, + struct gk20a *g, void *args) +{ + int ret = UNIT_SUCCESS; + u32 timer0; /* low bits */ + u32 timer1; /* high bits */ + u64 time; + int err; /* return from API */ + + /* Standard, successful, easy case where there's no wrap */ + timer0 = 1; + timer1 = 2; + nvgpu_posix_io_writel_reg_space(g, timer_time_0_r(), timer0); + timer1_index = 0; + timer1_values[timer1_index] = timer1; + timer1_values[timer1_index + 1] = timer1; + err = g->ops.ptimer.read_ptimer(g, &time); + if ((err != 0) || (time != ((u64)timer1 << 32 | timer0))) { + unit_err(m, "ptimer read_timer failed simple test, err=%d, time=0x%016llx\n", + err, time); + ret = UNIT_FAIL; + } + + /* Wrap timer1 once */ + timer0 = 1; + nvgpu_posix_io_writel_reg_space(g, timer_time_0_r(), timer0); + timer1 = 3; + timer1_index = 0; + timer1_values[timer1_index] = timer1 + 1; + timer1_values[timer1_index + 1] = timer1; + timer1_values[timer1_index + 2] = timer1; + timer1_values[timer1_index + 3] = timer1 - 1; + err = g->ops.ptimer.read_ptimer(g, &time); + if ((err != 0) || (time != ((u64)timer1 << 32 | timer0))) { + unit_err(m, "ptimer read_timer failed single wrap test, err=%d, time=0x%016llx\n", + err, time); + ret = UNIT_FAIL; + } + + /* Wrap timer1 every time to timeout */ + timer0 = 1; + nvgpu_posix_io_writel_reg_space(g, timer_time_0_r(), timer0); + timer1_index = 0; + timer1_values[timer1_index] = 4; + timer1_values[timer1_index + 1] = 3; + timer1_values[timer1_index + 2] = 2; + timer1_values[timer1_index + 3] = 1; + err = g->ops.ptimer.read_ptimer(g, &time); + if (err == 0) { + unit_err(m, "ptimer read_timer failed multiple wrap test\n"); + ret = UNIT_FAIL; + } + + /* branch testing */ + err = g->ops.ptimer.read_ptimer(g, NULL); + if (err == 0) { + unit_err(m, "ptimer read_timer failed branch test\n"); + ret = UNIT_FAIL; + } + + return ret; +} + +static u32 received_error_code; +static void mock_decode_error_code(struct gk20a *g, u32 error_code) +{ + received_error_code = error_code; +} + +int test_ptimer_isr(struct unit_module *m, + struct gk20a *g, void *args) +{ + int ret = UNIT_SUCCESS; + int val0, val1; + u32 fecs_errcode = 0xa5; + + /* initialize regs to defaults */ + nvgpu_posix_io_writel_reg_space(g, timer_pri_timeout_save_0_r(), 0); + nvgpu_posix_io_writel_reg_space(g, timer_pri_timeout_save_1_r(), 0); + nvgpu_posix_io_writel_reg_space(g, timer_pri_timeout_fecs_errcode_r(), + 0); + + /* all zero test */ + g->ops.ptimer.isr(g); + val0 = nvgpu_posix_io_readl_reg_space(g, timer_pri_timeout_save_0_r()); + val1 = nvgpu_posix_io_readl_reg_space(g, timer_pri_timeout_save_1_r()); + if ((val0 != 0) || (val1 != 0)) { + unit_err(m, "ptimer isr failed to clear regs\n"); + ret = UNIT_FAIL; + } + + /* set fecs bits */ + nvgpu_posix_io_writel_reg_space(g, timer_pri_timeout_save_0_r(), + ((u32)1 << 31)); + nvgpu_posix_io_writel_reg_space(g, timer_pri_timeout_fecs_errcode_r(), + fecs_errcode); + g->ops.ptimer.isr(g); + val0 = nvgpu_posix_io_readl_reg_space(g, timer_pri_timeout_save_0_r()); + val1 = nvgpu_posix_io_readl_reg_space(g, timer_pri_timeout_save_1_r()); + if ((val0 != 0) || (val1 != 0)) { + unit_err(m, "ptimer isr failed to clear regs\n"); + ret = UNIT_FAIL; + } + + /* with fecs set and a decode HAL to call */ + g->ops.priv_ring.decode_error_code = mock_decode_error_code; + nvgpu_posix_io_writel_reg_space(g, timer_pri_timeout_save_0_r(), + ((u32)1 << 31)); + nvgpu_posix_io_writel_reg_space(g, timer_pri_timeout_fecs_errcode_r(), + fecs_errcode); + g->ops.ptimer.isr(g); + if (received_error_code != fecs_errcode) { + unit_err(m, "ptimer isr failed pass err code to HAL\n"); + ret = UNIT_FAIL; + } + val0 = nvgpu_posix_io_readl_reg_space(g, timer_pri_timeout_save_0_r()); + val1 = nvgpu_posix_io_readl_reg_space(g, timer_pri_timeout_save_1_r()); + if ((val0 != 0) || (val1 != 0)) { + unit_err(m, "ptimer isr failed to clear regs\n"); + ret = UNIT_FAIL; + } + + /* Set save0 timeout bit to get a branch covered */ + nvgpu_posix_io_writel_reg_space(g, timer_pri_timeout_save_0_r(), + ((u32)1 << 1)); + nvgpu_posix_io_writel_reg_space(g, timer_pri_timeout_fecs_errcode_r(), + 0); + g->ops.ptimer.isr(g); + val0 = nvgpu_posix_io_readl_reg_space(g, timer_pri_timeout_save_0_r()); + val1 = nvgpu_posix_io_readl_reg_space(g, timer_pri_timeout_save_1_r()); + if ((val0 != 0) || (val1 != 0)) { + unit_err(m, "ptimer isr failed to clear regs\n"); + ret = UNIT_FAIL; + } + + return ret; +} + +int test_ptimer_scaling(struct unit_module *m, + struct gk20a *g, void *args) +{ + int ret = UNIT_SUCCESS; + u32 val; + + val = scale_ptimer(100, 20); + if (val != 50) { + unit_err(m, "ptimer scale calculation incorrect\n"); + ret = UNIT_FAIL; + } + + val = scale_ptimer(111, 20); + if (val != 56) { + unit_err(m, "ptimer scale calculation incorrect\n"); + ret = UNIT_FAIL; + } + + val = scale_ptimer(U32_MAX/10, 20); + if (val != (U32_MAX/20)+1) { + unit_err(m, "ptimer scale calculation incorrect\n"); + ret = UNIT_FAIL; + } + + val = scale_ptimer(0, U32_MAX); + if (val != 0) { + unit_err(m, "ptimer scale calculation incorrect\n"); + ret = UNIT_FAIL; + } + + val = scale_ptimer(100, 1); + if (val != 1001) { + unit_err(m, "ptimer scale calculation incorrect\n"); + ret = UNIT_FAIL; + } + + val = ptimer_scalingfactor10x(100); + if (val != (PTIMER_REF_FREQ_HZ*10/100)) { + unit_err(m, "ptimer scale calculation incorrect\n"); + ret = UNIT_FAIL; + } + + val = ptimer_scalingfactor10x(97); + if (val != (PTIMER_REF_FREQ_HZ*10/97)) { + unit_err(m, "ptimer scale calculation incorrect\n"); + ret = UNIT_FAIL; + } + + val = ptimer_scalingfactor10x(100); + if (val != (PTIMER_REF_FREQ_HZ*10/100)) { + unit_err(m, "ptimer scale calculation incorrect\n"); + ret = UNIT_FAIL; + } + + val = ptimer_scalingfactor10x(PTIMER_REF_FREQ_HZ); + if (val != 10) { + unit_err(m, "ptimer scale calculation incorrect\n"); + ret = UNIT_FAIL; + } + + return ret; +} + +struct unit_module_test ptimer_tests[] = { + UNIT_TEST(ptimer_setup_env, test_setup_env, NULL, 0), + UNIT_TEST(ptimer_read_ptimer, test_read_ptimer, NULL, 0), + UNIT_TEST(ptimer_isr, test_ptimer_isr, NULL, 0), + UNIT_TEST(ptimer_scaling, test_ptimer_scaling, NULL, 0), + UNIT_TEST(ptimer_free_env, test_free_env, NULL, 0), +}; + +UNIT_MODULE(ptimer, ptimer_tests, UNIT_PRIO_NVGPU_TEST); diff --git a/userspace/units/ptimer/nvgpu-ptimer.h b/userspace/units/ptimer/nvgpu-ptimer.h new file mode 100644 index 000000000..da889a9b8 --- /dev/null +++ b/userspace/units/ptimer/nvgpu-ptimer.h @@ -0,0 +1,174 @@ +/* + * 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_PTIMER_H +#define UNIT_NVGPU_PTIMER_H + +struct gk20a; +struct unit_module; + +/** @addtogroup SWUTS-ptimer + * @{ + * + * Software Unit Test Specification for nvgpu.common.ptimer + */ + +/** + * Test specification for: test_setup_env + * + * Description: Setup prerequisites for tests. + * + * Test Type: Other (setup) + * + * Input: None + * + * Steps: + * - Setup ptimer HAL function pointers. + * - Setup timer reg space in mockio. + * + * Output: + * - UNIT_FAIL if encounters an error creating reg space + * - UNIT_SUCCESS otherwise + */ +int test_setup_env(struct unit_module *m, + struct gk20a *g, void *args); + +/** + * Test specification for: test_free_env + * + * Description: Release resources from test_setup_env() + * + * Test Type: Other (setup) + * + * Input: test_setup_env() has been executed. + * + * Steps: + * - Delete ptimer register space from mockio. + * + * Output: + * - UNIT_FAIL if encounters an error creating reg space + * - UNIT_SUCCESS otherwise + */ +int test_free_env(struct unit_module *m, + struct gk20a *g, void *args); + +/** + * Test specification for: test_read_ptimer + * + * Description: Verify the read_ptimer API. + * + * Test Type: Feature Based + * + * Input: None + * + * Steps: + * - Test case where the ptimer time values do not wrap. + * - Write values to ptimer regs timer_time_0 and timer_time_1 in mockio + * register space. + * - Call read_timer API. + * - Verify the expected value is returned. + * - Test case where ptimer time values wrap once. + * - Configure mockio so that the timer_time_1 register reads a different + * value after the 1st read, but is consistent after 2nd read. + * - Call read_timer API. + * - Verify the expected value is returned. + * - Test case where ptimer time values wrap once. + * - Configure mockio so that the timer_time_1 register reads a different + * value for up to 4 reads. + * - Call read_timer API. + * - Verify API returns an error. + * - Test parameter checking of the API + * - Call read_timer API with a NULL pointer for the time parameter. + * - Verify API returns an error. + * + * Output: + * - UNIT_FAIL if encounters an error creating reg space + * - UNIT_SUCCESS otherwise + */ +int test_read_ptimer(struct unit_module *m, + struct gk20a *g, void *args); + +/** + * Test specification for: test_ptimer_isr + * + * Description: Verify the ptimer isr API. The ISR only logs the errors and + * clears the ISR regs. This test verifies the code paths do not + * cause errors. + * + * Test Type: Feature Based + * + * Input: None + * + * Steps: + * - Test isr with 0 register values. + * - Initialize registers to 0: pri_timeout_save_0, pri_timeout_save_1, + * pri_timeout_fecs_errcode. + * - Call isr API. + * - Verify the save_* regs were all set to 0. + * - Test with FECS bits set. + * - Set the fecs bit in the pri_timeout_save_0 reg and an error code in the + * pri_timeout_fecs_errcode reg. + * - Call isr API. + * - Verify the save_* regs were all set to 0. + * - Test with FECS bits set and verify priv_ring decode error HAL is invoked. + * - Set the fecs bit in the pri_timeout_save_0 reg and an error code in the + * pri_timeout_fecs_errcode reg. + * - Set the HAL priv_ring.decode_error_code to a mock function. + * - Call isr API. + * - Verify the fecs error code was passed to the decode_error_code mock + * function. + * - Verify the save_* regs were all set to 0. + * - Test branch for save0 timeout bit being set. + * - Set the timeout bit in the pri_timeout_save_0 reg. + * - Call isr API. + * - Verify the save_* regs were all set to 0. + * + * Output: + * - UNIT_FAIL if encounters an error creating reg space + * - UNIT_SUCCESS otherwise + */ +int test_ptimer_isr(struct unit_module *m, + struct gk20a *g, void *args); + +/** + * Test specification for: test_ptimer_scaling + * + * Description: Verify the scale_ptimer() and ptimer_scalingfactor10x() APIs. + * + * Test Type: Feature Based + * + * Input: None + * + * Steps: + * - Call the scale_ptimer() API with various input values and verify the + * returned value. + * - Call the ptimer_scalingfactor10x() API with various input values and verify + * the returned value. + * + * Output: + * - UNIT_FAIL if encounters an error creating reg space + * - UNIT_SUCCESS otherwise + */ +int test_ptimer_scaling(struct unit_module *m, + struct gk20a *g, void *args); + +#endif /* UNIT_NVGPU_PTIMER_H */