From 2f26b5849e6939e4622d30551a13c6f55ccde38a Mon Sep 17 00:00:00 2001 From: Vishal Aslot Date: Wed, 27 Sep 2023 01:16:22 +0000 Subject: [PATCH] tegra: hwpm: th500: Add support for MCF SOC This patch adds support for MCF SOC performance monitoring in the driver. MCF SOC has two different types of perfmuxes connected to the same perfmon: one is the OCU type and the other is IBHX and OBHX. IBHX is only accessible via MC16 aperture. Therefore, this patch adds two separate IPs: OCU and IOBHX. However, both are tied to the MCF SOC perfmon (mcfsoc0). Bug 4287384 Signed-off-by: Vishal Aslot Change-Id: If15498a44e02270f9106337078931edbe043c254 Reviewed-on: https://git-master.nvidia.com/r/c/linux-hwpm/+/2986232 GVS: Gerrit_Virtual_Submit Reviewed-by: Vedashree Vidwans --- drivers/tegra/hwpm/Makefile.th500.soc.sources | 6 + .../th500/soc/ip/mcf_iobhx/th500_mcf_iobhx.c | 215 +++++++++++++++ .../th500/soc/ip/mcf_iobhx/th500_mcf_iobhx.h | 48 ++++ .../hal/th500/soc/ip/mcf_ocu/th500_mcf_ocu.c | 245 ++++++++++++++++++ .../hal/th500/soc/ip/mcf_ocu/th500_mcf_ocu.h | 48 ++++ .../th500/soc/th500_soc_regops_allowlist.c | 6 +- .../th500/soc/th500_soc_regops_allowlist.h | 3 +- .../tegra/hwpm/hal/th500/th500_interface.c | 32 ++- drivers/tegra/hwpm/hal/th500/th500_internal.h | 4 + drivers/tegra/hwpm/hal/th500/th500_ip.c | 36 ++- drivers/tegra/hwpm/include/tegra_hwpm.h | 4 + drivers/tegra/hwpm/os/linux/ip_utils.c | 12 + include/uapi/linux/tegra-soc-hwpm-uapi.h | 4 + 13 files changed, 647 insertions(+), 16 deletions(-) create mode 100644 drivers/tegra/hwpm/hal/th500/soc/ip/mcf_iobhx/th500_mcf_iobhx.c create mode 100644 drivers/tegra/hwpm/hal/th500/soc/ip/mcf_iobhx/th500_mcf_iobhx.h create mode 100644 drivers/tegra/hwpm/hal/th500/soc/ip/mcf_ocu/th500_mcf_ocu.c create mode 100644 drivers/tegra/hwpm/hal/th500/soc/ip/mcf_ocu/th500_mcf_ocu.h diff --git a/drivers/tegra/hwpm/Makefile.th500.soc.sources b/drivers/tegra/hwpm/Makefile.th500.soc.sources index edc9f2a..b82500d 100644 --- a/drivers/tegra/hwpm/Makefile.th500.soc.sources +++ b/drivers/tegra/hwpm/Makefile.th500.soc.sources @@ -57,4 +57,10 @@ nvhwpm-th500-soc-objs += hal/th500/soc/ip/c_nvlink/th500_nvlctrl.o ccflags-y += -DCONFIG_TH500_HWPM_IP_MSS_HUB nvhwpm-th500-soc-objs += hal/th500/soc/ip/mss_hub/th500_mss_hub.o +ccflags-y += -DCONFIG_TH500_HWPM_IP_MCF_OCU +nvhwpm-th500-soc-objs += hal/th500/soc/ip/mcf_ocu/th500_mcf_ocu.o + +ccflags-y += -DCONFIG_TH500_HWPM_IP_MCF_IOBHX +nvhwpm-th500-soc-objs += hal/th500/soc/ip/mcf_iobhx/th500_mcf_iobhx.o + endif diff --git a/drivers/tegra/hwpm/hal/th500/soc/ip/mcf_iobhx/th500_mcf_iobhx.c b/drivers/tegra/hwpm/hal/th500/soc/ip/mcf_iobhx/th500_mcf_iobhx.c new file mode 100644 index 0000000..a375787 --- /dev/null +++ b/drivers/tegra/hwpm/hal/th500/soc/ip/mcf_iobhx/th500_mcf_iobhx.c @@ -0,0 +1,215 @@ +// SPDX-License-Identifier: MIT +/* + * SPDX-FileCopyrightText: Copyright (c) 2023 NVIDIA CORPORATION & AFFILIATES. 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. + * + * This is a generated file. Do not edit. + * + * Steps to regenerate: + * python3 ip_files_generator.py [] + */ + +#include "th500_mcf_iobhx.h" + +#include +#include +#include +#include + +static struct hwpm_ip_aperture th500_mcf_iobhx_inst0_perfmon_element_static_array[ + TH500_HWPM_IP_MCF_IOBHX_NUM_PERFMON_PER_INST] = { + { + .element_type = HWPM_ELEMENT_PERFMON, + .element_index_mask = BIT(0), + .element_index = 0U, + .dt_mmio = NULL, + .name = "permon_mcfsoc0_iobhx", + .device_index = TH500_MCFSOC0_PERFMON_DEVICE_NODE_INDEX, + .start_abs_pa = addr_map_rpg_pm_mcfsoc0_base_r(), + .end_abs_pa = addr_map_rpg_pm_mcfsoc0_limit_r(), + .start_pa = addr_map_rpg_pm_mcfsoc0_base_r(), + .end_pa = addr_map_rpg_pm_mcfsoc0_limit_r(), + .base_pa = addr_map_rpg_pm_base_r(), + .alist = th500_perfmon_alist, + .alist_size = ARRAY_SIZE(th500_perfmon_alist), + .fake_registers = NULL, + }, +}; + +static struct hwpm_ip_aperture th500_mcf_iobhx_inst0_perfmux_element_static_array[ + TH500_HWPM_IP_MCF_IOBHX_NUM_PERFMUX_PER_INST] = { + { + .element_type = IP_ELEMENT_PERFMUX, + .element_index_mask = BIT(0), + .element_index = 17U, + .dt_mmio = NULL, + .name = {'\0'}, + .start_abs_pa = addr_map_mc16_base_r(), + .end_abs_pa = addr_map_mc16_limit_r(), + .start_pa = addr_map_mc16_base_r(), + .end_pa = addr_map_mc16_limit_r(), + .base_pa = 0ULL, + .alist = th500_mcf_iobhx_alist, + .alist_size = ARRAY_SIZE(th500_mcf_iobhx_alist), + .fake_registers = NULL, + }, +}; + +static struct hwpm_ip_aperture th500_mcf_iobhx_inst0_broadcast_element_static_array[ + TH500_HWPM_IP_MCF_IOBHX_NUM_BROADCAST_PER_INST] = { + { + .element_type = IP_ELEMENT_BROADCAST, + .element_index_mask = BIT(0), + .element_index = 0U, + .dt_mmio = NULL, + .name = {'\0'}, + .start_abs_pa = addr_map_mcb_base_r(), + .end_abs_pa = addr_map_mcb_limit_r(), + .start_pa = addr_map_mcb_base_r(), + .end_pa = addr_map_mcb_limit_r(), + .base_pa = 0ULL, + .alist = th500_mcf_iobhx_alist, + .alist_size = ARRAY_SIZE(th500_mcf_iobhx_alist), + .fake_registers = NULL, + }, +}; + +/* IP instance array */ +static struct hwpm_ip_inst th500_mcf_iobhx_inst_static_array[ + TH500_HWPM_IP_MCF_IOBHX_NUM_INSTANCES] = { + { + .hw_inst_mask = BIT(0), + .num_core_elements_per_inst = + TH500_HWPM_IP_MCF_IOBHX_NUM_CORE_ELEMENT_PER_INST, + .element_info = { + /* + * Instance info corresponding to + * TEGRA_HWPM_APERTURE_TYPE_PERFMUX + */ + { + .num_element_per_inst = + TH500_HWPM_IP_MCF_IOBHX_NUM_PERFMUX_PER_INST, + .element_static_array = + th500_mcf_iobhx_inst0_perfmux_element_static_array, + /* NOTE: range should be in ascending order */ + .range_start = addr_map_mc16_base_r(), + .range_end = addr_map_mc16_limit_r(), + .element_stride = addr_map_mc16_limit_r() - + addr_map_mc16_base_r() + 1ULL, + .element_slots = 0U, + .element_arr = NULL, + }, + /* + * Instance info corresponding to + * TEGRA_HWPM_APERTURE_TYPE_BROADCAST + */ + { + .num_element_per_inst = + TH500_HWPM_IP_MCF_IOBHX_NUM_BROADCAST_PER_INST, + .element_static_array = + th500_mcf_iobhx_inst0_broadcast_element_static_array, + .range_start = addr_map_mcb_base_r(), + .range_end = addr_map_mcb_limit_r(), + .element_stride = addr_map_mcb_limit_r() - + addr_map_mcb_base_r() + 1ULL, + .element_slots = 0U, + .element_arr = NULL, + }, + /* + * Instance info corresponding to + * TEGRA_HWPM_APERTURE_TYPE_PERFMON + */ + { + .num_element_per_inst = + TH500_HWPM_IP_MCF_IOBHX_NUM_PERFMON_PER_INST, + .element_static_array = + th500_mcf_iobhx_inst0_perfmon_element_static_array, + .range_start = addr_map_rpg_pm_mcfsoc0_base_r(), + .range_end = addr_map_rpg_pm_mcfsoc0_limit_r(), + .element_stride = addr_map_rpg_pm_mcfsoc0_limit_r() - + addr_map_rpg_pm_mcfsoc0_base_r() + 1ULL, + .element_slots = 0U, + .element_arr = NULL, + }, + }, + + .ip_ops = { + .ip_dev = NULL, + .hwpm_ip_pm = NULL, + .hwpm_ip_reg_op = NULL, + .fd = TEGRA_HWPM_IP_DEBUG_FD_INVALID, + }, + + .element_fs_mask = 0U, + .dev_name = "", + }, +}; + +/* IP structure */ +struct hwpm_ip th500_hwpm_ip_mcf_iobhx = { + .num_instances = TH500_HWPM_IP_MCF_IOBHX_NUM_INSTANCES, + .ip_inst_static_array = th500_mcf_iobhx_inst_static_array, + + .inst_aperture_info = { + /* + * Instance info corresponding to + * TEGRA_HWPM_APERTURE_TYPE_PERFMUX + */ + { + /* NOTE: range should be in ascending order */ + .range_start = addr_map_mc16_base_r(), + .range_end = addr_map_mc16_limit_r(), + .inst_stride = addr_map_mc16_limit_r() - + addr_map_mc16_base_r() + 1ULL, + .inst_slots = 0U, + .inst_arr = NULL, + }, + /* + * Instance info corresponding to + * TEGRA_HWPM_APERTURE_TYPE_BROADCAST + */ + { + .range_start = addr_map_mcb_base_r(), + .range_end = addr_map_mcb_limit_r(), + .inst_stride = addr_map_mcb_limit_r() - + addr_map_mcb_base_r() + 1ULL, + .inst_slots = 0U, + .inst_arr = NULL, + }, + /* + * Instance info corresponding to + * TEGRA_HWPM_APERTURE_TYPE_PERFMON + */ + { + .range_start = addr_map_rpg_pm_mcfsoc0_base_r(), + .range_end = addr_map_rpg_pm_mcfsoc0_limit_r(), + .inst_stride = addr_map_rpg_pm_mcfsoc0_limit_r() - + addr_map_rpg_pm_mcfsoc0_base_r() + 1ULL, + .inst_slots = 0U, + .inst_arr = NULL, + }, + }, + + .dependent_fuse_mask = TEGRA_HWPM_FUSE_SECURITY_MODE_MASK | TEGRA_HWPM_FUSE_HWPM_GLOBAL_DISABLE_MASK, + .override_enable = false, + .inst_fs_mask = 0U, + .resource_status = TEGRA_HWPM_RESOURCE_STATUS_INVALID, + .reserved = false, +}; diff --git a/drivers/tegra/hwpm/hal/th500/soc/ip/mcf_iobhx/th500_mcf_iobhx.h b/drivers/tegra/hwpm/hal/th500/soc/ip/mcf_iobhx/th500_mcf_iobhx.h new file mode 100644 index 0000000..e6327b7 --- /dev/null +++ b/drivers/tegra/hwpm/hal/th500/soc/ip/mcf_iobhx/th500_mcf_iobhx.h @@ -0,0 +1,48 @@ +/* SPDX-License-Identifier: MIT */ +/* + * SPDX-FileCopyrightText: Copyright (c) 2023 NVIDIA CORPORATION & AFFILIATES. 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. + * + * This is a generated file. Do not edit. + * + * Steps to regenerate: + * python3 ip_files_generator.py [] + */ + +#ifndef TH500_HWPM_IP_MCF_IOBHX_H +#define TH500_HWPM_IP_MCF_IOBHX_H + +#if defined(CONFIG_TH500_HWPM_IP_MCF_IOBHX) +#define TH500_HWPM_ACTIVE_IP_MCF_IOBHX TH500_HWPM_IP_MCF_IOBHX, + +/* This data should ideally be available in HW headers */ +#define TH500_HWPM_IP_MCF_IOBHX_NUM_INSTANCES 1U +#define TH500_HWPM_IP_MCF_IOBHX_NUM_CORE_ELEMENT_PER_INST 1U +#define TH500_HWPM_IP_MCF_IOBHX_NUM_PERFMON_PER_INST 1U +#define TH500_HWPM_IP_MCF_IOBHX_NUM_PERFMUX_PER_INST 1U +#define TH500_HWPM_IP_MCF_IOBHX_NUM_BROADCAST_PER_INST 1U + +extern struct hwpm_ip th500_hwpm_ip_mcf_iobhx; + +#else +#define TH500_HWPM_ACTIVE_IP_MCF_IOBHX +#endif + +#endif /* TH500_HWPM_IP_MCF_IOBHX_H */ diff --git a/drivers/tegra/hwpm/hal/th500/soc/ip/mcf_ocu/th500_mcf_ocu.c b/drivers/tegra/hwpm/hal/th500/soc/ip/mcf_ocu/th500_mcf_ocu.c new file mode 100644 index 0000000..c7518d1 --- /dev/null +++ b/drivers/tegra/hwpm/hal/th500/soc/ip/mcf_ocu/th500_mcf_ocu.c @@ -0,0 +1,245 @@ +// SPDX-License-Identifier: MIT +/* + * SPDX-FileCopyrightText: Copyright (c) 2023 NVIDIA CORPORATION & AFFILIATES. 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. + * + * This is a generated file. Do not edit. + * + * Steps to regenerate: + * python3 ip_files_generator.py [] + */ + +#include "th500_mcf_ocu.h" + +#include +#include +#include +#include + +static struct hwpm_ip_aperture th500_mcf_ocu_inst0_perfmon_element_static_array[ + TH500_HWPM_IP_MCF_OCU_NUM_PERFMON_PER_INST] = { + { + .element_type = HWPM_ELEMENT_PERFMON, + .element_index_mask = BIT(0), + .element_index = 0U, + .dt_mmio = NULL, + .name = "permon_mcfsoc0_ocu", + .device_index = TH500_MCFSOC0_PERFMON_DEVICE_NODE_INDEX, + .start_abs_pa = addr_map_rpg_pm_mcfsoc0_base_r(), + .end_abs_pa = addr_map_rpg_pm_mcfsoc0_limit_r(), + .start_pa = addr_map_rpg_pm_mcfsoc0_base_r(), + .end_pa = addr_map_rpg_pm_mcfsoc0_limit_r(), + .base_pa = addr_map_rpg_pm_base_r(), + .alist = th500_perfmon_alist, + .alist_size = ARRAY_SIZE(th500_perfmon_alist), + .fake_registers = NULL, + }, +}; + +static struct hwpm_ip_aperture th500_mcf_ocu_inst0_perfmux_element_static_array[ + TH500_HWPM_IP_MCF_OCU_NUM_PERFMUX_PER_INST] = { + { + .element_type = IP_ELEMENT_PERFMUX, + .element_index_mask = BIT(0), + .element_index = 1U, + .dt_mmio = NULL, + .name = {'\0'}, + .start_abs_pa = addr_map_mc0_base_r(), + .end_abs_pa = addr_map_mc0_limit_r(), + .start_pa = addr_map_mc0_base_r(), + .end_pa = addr_map_mc0_limit_r(), + .base_pa = 0ULL, + .alist = th500_mcf_ocu_alist, + .alist_size = ARRAY_SIZE(th500_mcf_ocu_alist), + .fake_registers = NULL, + }, + { + .element_type = IP_ELEMENT_PERFMUX, + .element_index_mask = BIT(1), + .element_index = 2U, + .dt_mmio = NULL, + .name = {'\0'}, + .start_abs_pa = addr_map_mc1_base_r(), + .end_abs_pa = addr_map_mc1_limit_r(), + .start_pa = addr_map_mc1_base_r(), + .end_pa = addr_map_mc1_limit_r(), + .base_pa = 0ULL, + .alist = th500_mcf_ocu_alist, + .alist_size = ARRAY_SIZE(th500_mcf_ocu_alist), + .fake_registers = NULL, + }, + { + .element_type = IP_ELEMENT_PERFMUX, + .element_index_mask = BIT(2), + .element_index = 3U, + .dt_mmio = NULL, + .name = {'\0'}, + .start_abs_pa = addr_map_mc2_base_r(), + .end_abs_pa = addr_map_mc2_limit_r(), + .start_pa = addr_map_mc2_base_r(), + .end_pa = addr_map_mc2_limit_r(), + .base_pa = 0ULL, + .alist = th500_mcf_ocu_alist, + .alist_size = ARRAY_SIZE(th500_mcf_ocu_alist), + .fake_registers = NULL, + }, +}; + +static struct hwpm_ip_aperture th500_mcf_ocu_inst0_broadcast_element_static_array[ + TH500_HWPM_IP_MCF_OCU_NUM_BROADCAST_PER_INST] = { + { + .element_type = IP_ELEMENT_BROADCAST, + .element_index_mask = BIT(0), + .element_index = 0U, + .dt_mmio = NULL, + .name = {'\0'}, + .start_abs_pa = addr_map_mcb_base_r(), + .end_abs_pa = addr_map_mcb_limit_r(), + .start_pa = addr_map_mcb_base_r(), + .end_pa = addr_map_mcb_limit_r(), + .base_pa = 0ULL, + .alist = th500_mcf_ocu_alist, + .alist_size = ARRAY_SIZE(th500_mcf_ocu_alist), + .fake_registers = NULL, + }, +}; + +/* IP instance array */ +static struct hwpm_ip_inst th500_mcf_ocu_inst_static_array[ + TH500_HWPM_IP_MCF_OCU_NUM_INSTANCES] = { + { + .hw_inst_mask = BIT(0), + .num_core_elements_per_inst = + TH500_HWPM_IP_MCF_OCU_NUM_CORE_ELEMENT_PER_INST, + .element_info = { + /* + * Instance info corresponding to + * TEGRA_HWPM_APERTURE_TYPE_PERFMUX + */ + { + .num_element_per_inst = + TH500_HWPM_IP_MCF_OCU_NUM_PERFMUX_PER_INST, + .element_static_array = + th500_mcf_ocu_inst0_perfmux_element_static_array, + /* NOTE: range should be in ascending order */ + .range_start = addr_map_mc0_base_r(), + .range_end = addr_map_mc2_limit_r(), + .element_stride = addr_map_mc0_limit_r() - + addr_map_mc0_base_r() + 1ULL, + .element_slots = 0U, + .element_arr = NULL, + }, + /* + * Instance info corresponding to + * TEGRA_HWPM_APERTURE_TYPE_BROADCAST + */ + { + .num_element_per_inst = + TH500_HWPM_IP_MCF_OCU_NUM_BROADCAST_PER_INST, + .element_static_array = + th500_mcf_ocu_inst0_broadcast_element_static_array, + .range_start = addr_map_mcb_base_r(), + .range_end = addr_map_mcb_limit_r(), + .element_stride = addr_map_mcb_limit_r() - + addr_map_mcb_base_r() + 1ULL, + .element_slots = 0U, + .element_arr = NULL, + }, + /* + * Instance info corresponding to + * TEGRA_HWPM_APERTURE_TYPE_PERFMON + */ + { + .num_element_per_inst = + TH500_HWPM_IP_MCF_OCU_NUM_PERFMON_PER_INST, + .element_static_array = + th500_mcf_ocu_inst0_perfmon_element_static_array, + .range_start = addr_map_rpg_pm_mcfsoc0_base_r(), + .range_end = addr_map_rpg_pm_mcfsoc0_limit_r(), + .element_stride = addr_map_rpg_pm_mcfsoc0_limit_r() - + addr_map_rpg_pm_mcfsoc0_base_r() + 1ULL, + .element_slots = 0U, + .element_arr = NULL, + }, + }, + + .ip_ops = { + .ip_dev = NULL, + .hwpm_ip_pm = NULL, + .hwpm_ip_reg_op = NULL, + .fd = TEGRA_HWPM_IP_DEBUG_FD_INVALID, + }, + + .element_fs_mask = 0U, + .dev_name = "", + }, +}; + +/* IP structure */ +struct hwpm_ip th500_hwpm_ip_mcf_ocu = { + .num_instances = TH500_HWPM_IP_MCF_OCU_NUM_INSTANCES, + .ip_inst_static_array = th500_mcf_ocu_inst_static_array, + + .inst_aperture_info = { + /* + * Instance info corresponding to + * TEGRA_HWPM_APERTURE_TYPE_PERFMUX + */ + { + /* NOTE: range should be in ascending order */ + .range_start = addr_map_mc0_base_r(), + .range_end = addr_map_mc2_limit_r(), + .inst_stride = addr_map_mc2_limit_r() - + addr_map_mc0_base_r() + 1ULL, + .inst_slots = 0U, + .inst_arr = NULL, + }, + /* + * Instance info corresponding to + * TEGRA_HWPM_APERTURE_TYPE_BROADCAST + */ + { + .range_start = addr_map_mcb_base_r(), + .range_end = addr_map_mcb_limit_r(), + .inst_stride = addr_map_mcb_limit_r() - + addr_map_mcb_base_r() + 1ULL, + .inst_slots = 0U, + .inst_arr = NULL, + }, + /* + * Instance info corresponding to + * TEGRA_HWPM_APERTURE_TYPE_PERFMON + */ + { + .range_start = addr_map_rpg_pm_mcfsoc0_base_r(), + .range_end = addr_map_rpg_pm_mcfsoc0_limit_r(), + .inst_stride = addr_map_rpg_pm_mcfsoc0_limit_r() - + addr_map_rpg_pm_mcfsoc0_base_r() + 1ULL, + .inst_slots = 0U, + .inst_arr = NULL, + }, + }, + + .dependent_fuse_mask = TEGRA_HWPM_FUSE_SECURITY_MODE_MASK | TEGRA_HWPM_FUSE_HWPM_GLOBAL_DISABLE_MASK, + .override_enable = false, + .inst_fs_mask = 0U, + .resource_status = TEGRA_HWPM_RESOURCE_STATUS_INVALID, + .reserved = false, +}; diff --git a/drivers/tegra/hwpm/hal/th500/soc/ip/mcf_ocu/th500_mcf_ocu.h b/drivers/tegra/hwpm/hal/th500/soc/ip/mcf_ocu/th500_mcf_ocu.h new file mode 100644 index 0000000..d2f61b2 --- /dev/null +++ b/drivers/tegra/hwpm/hal/th500/soc/ip/mcf_ocu/th500_mcf_ocu.h @@ -0,0 +1,48 @@ +/* SPDX-License-Identifier: MIT */ +/* + * SPDX-FileCopyrightText: Copyright (c) 2023 NVIDIA CORPORATION & AFFILIATES. 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. + * + * This is a generated file. Do not edit. + * + * Steps to regenerate: + * python3 ip_files_generator.py [] + */ + +#ifndef TH500_HWPM_IP_MCF_OCU_H +#define TH500_HWPM_IP_MCF_OCU_H + +#if defined(CONFIG_TH500_HWPM_IP_MCF_OCU) +#define TH500_HWPM_ACTIVE_IP_MCF_OCU TH500_HWPM_IP_MCF_OCU, + +/* This data should ideally be available in HW headers */ +#define TH500_HWPM_IP_MCF_OCU_NUM_INSTANCES 1U +#define TH500_HWPM_IP_MCF_OCU_NUM_CORE_ELEMENT_PER_INST 3U +#define TH500_HWPM_IP_MCF_OCU_NUM_PERFMON_PER_INST 1U +#define TH500_HWPM_IP_MCF_OCU_NUM_PERFMUX_PER_INST 3U +#define TH500_HWPM_IP_MCF_OCU_NUM_BROADCAST_PER_INST 1U + +extern struct hwpm_ip th500_hwpm_ip_mcf_ocu; + +#else +#define TH500_HWPM_ACTIVE_IP_MCF_OCU +#endif + +#endif /* TH500_HWPM_IP_MCF_OCU_H */ diff --git a/drivers/tegra/hwpm/hal/th500/soc/th500_soc_regops_allowlist.c b/drivers/tegra/hwpm/hal/th500/soc/th500_soc_regops_allowlist.c index 9287aa8..51bd89a 100644 --- a/drivers/tegra/hwpm/hal/th500/soc/th500_soc_regops_allowlist.c +++ b/drivers/tegra/hwpm/hal/th500/soc/th500_soc_regops_allowlist.c @@ -250,7 +250,11 @@ struct allowlist th500_mcf_c2c_alist[2] = { {0x0000d60c, false}, }; -struct allowlist th500_mcf_soc_alist[2] = { +struct allowlist th500_mcf_ocu_alist[1] = { + {0x0000d620, false}, +}; + +struct allowlist th500_mcf_iobhx_alist[2] = { {0x0000d618, false}, {0x0000d61c, false}, }; diff --git a/drivers/tegra/hwpm/hal/th500/soc/th500_soc_regops_allowlist.h b/drivers/tegra/hwpm/hal/th500/soc/th500_soc_regops_allowlist.h index d391f44..b1412be 100644 --- a/drivers/tegra/hwpm/hal/th500/soc/th500_soc_regops_allowlist.h +++ b/drivers/tegra/hwpm/hal/th500/soc/th500_soc_regops_allowlist.h @@ -35,7 +35,8 @@ extern struct allowlist th500_mss_channel_alist[2]; extern struct allowlist th500_mcf_core_alist[2]; extern struct allowlist th500_mcf_clink_alist[3]; extern struct allowlist th500_mcf_c2c_alist[2]; -extern struct allowlist th500_mcf_soc_alist[2]; +extern struct allowlist th500_mcf_ocu_alist[1]; +extern struct allowlist th500_mcf_iobhx_alist[2]; extern struct allowlist th500_soc_hub_alist[3]; extern struct allowlist th500_cl2_alist[4]; extern struct allowlist th500_mss_hub_alist[3]; diff --git a/drivers/tegra/hwpm/hal/th500/th500_interface.c b/drivers/tegra/hwpm/hal/th500/th500_interface.c index b140886..68fc722 100644 --- a/drivers/tegra/hwpm/hal/th500/th500_interface.c +++ b/drivers/tegra/hwpm/hal/th500/th500_interface.c @@ -148,9 +148,14 @@ bool th500_hwpm_is_ip_active(struct tegra_soc_hwpm *hwpm, config_ip = TH500_HWPM_IP_MCF_C2C; break; #endif -#if defined(CONFIG_TH500_HWPM_IP_MCF_SOC) - case TEGRA_HWPM_IP_MCF_SOC: - config_ip = TH500_HWPM_IP_MCF_SOC; +#if defined(CONFIG_TH500_HWPM_IP_MCF_OCU) + case TEGRA_HWPM_IP_MCF_OCU: + config_ip = TH500_HWPM_IP_MCF_OCU; + break; +#endif +#if defined(CONFIG_TH500_HWPM_IP_MCF_IOBHX) + case TEGRA_HWPM_IP_MCF_IOBHX: + config_ip = TH500_HWPM_IP_MCF_IOBHX; break; #endif #if defined(CONFIG_TH500_HWPM_IP_SMMU) @@ -225,9 +230,14 @@ bool th500_hwpm_is_resource_active(struct tegra_soc_hwpm *hwpm, config_ip = TH500_HWPM_IP_MCF_C2C; break; #endif -#if defined(CONFIG_TH500_HWPM_IP_MCF_SOC) - case TEGRA_HWPM_RESOURCE_MCF_SOC: - config_ip = TH500_HWPM_IP_MCF_SOC; +#if defined(CONFIG_TH500_HWPM_IP_MCF_OCU) + case TEGRA_HWPM_RESOURCE_MCF_OCU: + config_ip = TH500_HWPM_IP_MCF_OCU; + break; +#endif +#if defined(CONFIG_TH500_HWPM_IP_MCF_IOBHX) + case TEGRA_HWPM_RESOURCE_MCF_IOBHX: + config_ip = TH500_HWPM_IP_MCF_IOBHX; break; #endif #if defined(CONFIG_TH500_HWPM_IP_SMMU) @@ -321,9 +331,13 @@ int th500_hwpm_init_chip_info(struct tegra_soc_hwpm *hwpm) th500_active_ip_info[TH500_HWPM_IP_MCF_C2C] = &th500_hwpm_ip_mcf_c2c; #endif -#if defined(CONFIG_TH500_HWPM_IP_MCF_SOC) - th500_active_ip_info[TH500_HWPM_IP_MCF_SOC] = - &th500_hwpm_ip_mcf_soc; +#if defined(CONFIG_TH500_HWPM_IP_MCF_OCU) + th500_active_ip_info[TH500_HWPM_IP_MCF_OCU] = + &th500_hwpm_ip_mcf_ocu; +#endif +#if defined(CONFIG_TH500_HWPM_IP_MCF_IOBHX) + th500_active_ip_info[TH500_HWPM_IP_MCF_IOBHX] = + &th500_hwpm_ip_mcf_iobhx; #endif #if defined(CONFIG_TH500_HWPM_IP_SMMU) th500_active_ip_info[TH500_HWPM_IP_SMMU] = &th500_hwpm_ip_smmu; diff --git a/drivers/tegra/hwpm/hal/th500/th500_internal.h b/drivers/tegra/hwpm/hal/th500/th500_internal.h index 9458ed4..23a8b77 100644 --- a/drivers/tegra/hwpm/hal/th500/th500_internal.h +++ b/drivers/tegra/hwpm/hal/th500/th500_internal.h @@ -33,6 +33,8 @@ #include #include #include +#include +#include #define TH500_HWPM_ACTIVE_IP_MAX TH500_HWPM_IP_MAX @@ -47,6 +49,8 @@ DEFINE_SOC_HWPM_ACTIVE_IP(TH500_HWPM_ACTIVE_IP_NVLRX) \ DEFINE_SOC_HWPM_ACTIVE_IP(TH500_HWPM_ACTIVE_IP_NVLTX) \ DEFINE_SOC_HWPM_ACTIVE_IP(TH500_HWPM_ACTIVE_IP_MSS_HUB) \ + DEFINE_SOC_HWPM_ACTIVE_IP(TH500_HWPM_ACTIVE_IP_MCF_OCU) \ + DEFINE_SOC_HWPM_ACTIVE_IP(TH500_HWPM_ACTIVE_IP_MCF_IOBHX) \ DEFINE_SOC_HWPM_ACTIVE_IP(TH500_HWPM_ACTIVE_IP_MAX) #undef DEFINE_SOC_HWPM_ACTIVE_IP diff --git a/drivers/tegra/hwpm/hal/th500/th500_ip.c b/drivers/tegra/hwpm/hal/th500/th500_ip.c index 5dcd5fd..b755719 100644 --- a/drivers/tegra/hwpm/hal/th500/th500_ip.c +++ b/drivers/tegra/hwpm/hal/th500/th500_ip.c @@ -106,8 +106,11 @@ int th500_hwpm_extract_ip_ops(struct tegra_soc_hwpm *hwpm, #if defined(CONFIG_TH500_HWPM_IP_MCF_C2C) case TH500_HWPM_IP_MCF_C2C: #endif -#if defined(CONFIG_TH500_HWPM_IP_MCF_SOC) - case TH500_HWPM_IP_MCF_SOC: +#if defined(CONFIG_TH500_HWPM_IP_MCF_OCU) + case TH500_HWPM_IP_MCF_OCU: +#endif +#if defined(CONFIG_TH500_HWPM_IP_MCF_IOBHX) + case TH500_HWPM_IP_MCF_IOBHX: #endif /* * MSS channel, MCF CORE, MCF CLINK, MCF C2C, MCF SOC, @@ -206,9 +209,32 @@ int th500_hwpm_extract_ip_ops(struct tegra_soc_hwpm *hwpm, ret = 0; } #endif -#if defined(CONFIG_TH500_HWPM_IP_MCF_SOC) - /* Check base address in TH500_HWPM_IP_MCF_SOC */ - ip_idx = TH500_HWPM_IP_MCF_SOC; +#if defined(CONFIG_TH500_HWPM_IP_MCF_OCU) + /* Check base address in TH500_HWPM_IP_MCF_OCU */ + ip_idx = TH500_HWPM_IP_MCF_OCU; + ret = tegra_hwpm_set_fs_info_ip_ops(hwpm, ip_ops, + base_address, ip_idx, available); + if (ret != 0) { + /* + * Return value of ENODEV will indicate that the base + * address doesn't belong to this IP. + * This case is valid, as not all base addresses are + * shared between MSS IPs. + * In this case, reset return value to 0. + */ + if (ret != -ENODEV) { + tegra_hwpm_err(hwpm, + "IP %d base 0x%llx:Failed to %s fs/ops", + ip_idx, base_address, + available == true ? "set" : "reset"); + goto fail; + } + ret = 0; + } +#endif +#if defined(CONFIG_TH500_HWPM_IP_MCF_IOBHX) + /* Check base address in TH500_HWPM_IP_MCF_IOBHX */ + ip_idx = TH500_HWPM_IP_MCF_IOBHX; ret = tegra_hwpm_set_fs_info_ip_ops(hwpm, ip_ops, base_address, ip_idx, available); if (ret != 0) { diff --git a/drivers/tegra/hwpm/include/tegra_hwpm.h b/drivers/tegra/hwpm/include/tegra_hwpm.h index 563ca83..a8550ae 100644 --- a/drivers/tegra/hwpm/include/tegra_hwpm.h +++ b/drivers/tegra/hwpm/include/tegra_hwpm.h @@ -84,6 +84,8 @@ enum tegra_hwpm_ip_enum { TEGRA_HWPM_IP_NVLRX, TEGRA_HWPM_IP_NVLTX, TEGRA_HWPM_IP_MSS_HUB, + TEGRA_HWPM_IP_MCF_OCU, + TEGRA_HWPM_IP_MCF_IOBHX, TERGA_HWPM_NUM_IPS }; @@ -119,6 +121,8 @@ enum tegra_hwpm_resource_enum { TEGRA_HWPM_RESOURCE_NVLRX, TEGRA_HWPM_RESOURCE_NVLTX, TEGRA_HWPM_RESOURCE_MSS_HUB, + TEGRA_HWPM_RESOURCE_MCF_OCU, + TEGRA_HWPM_RESOURCE_MCF_IOBHX, TERGA_HWPM_NUM_RESOURCES }; diff --git a/drivers/tegra/hwpm/os/linux/ip_utils.c b/drivers/tegra/hwpm/os/linux/ip_utils.c index 15e4343..35cf346 100644 --- a/drivers/tegra/hwpm/os/linux/ip_utils.c +++ b/drivers/tegra/hwpm/os/linux/ip_utils.c @@ -108,6 +108,12 @@ static u32 tegra_hwpm_translate_soc_hwpm_ip(struct tegra_soc_hwpm *hwpm, case TEGRA_SOC_HWPM_IP_MSS_HUB: ip_enum_idx = TEGRA_HWPM_IP_MSS_HUB; break; + case TEGRA_SOC_HWPM_IP_MCF_OCU: + ip_enum_idx = TEGRA_HWPM_IP_MCF_OCU; + break; + case TEGRA_SOC_HWPM_IP_MCF_IOBHX: + ip_enum_idx = TEGRA_HWPM_IP_MCF_IOBHX; + break; default: tegra_hwpm_err(hwpm, "Queried enum tegra_soc_hwpm_ip %d is invalid", @@ -231,6 +237,12 @@ u32 tegra_hwpm_translate_soc_hwpm_resource(struct tegra_soc_hwpm *hwpm, case TEGRA_SOC_HWPM_RESOURCE_MSS_HUB: res_enum_idx = TEGRA_HWPM_RESOURCE_MSS_HUB; break; + case TEGRA_SOC_HWPM_RESOURCE_MCF_OCU: + res_enum_idx = TEGRA_HWPM_RESOURCE_MCF_OCU; + break; + case TEGRA_SOC_HWPM_RESOURCE_MCF_IOBHX: + res_enum_idx = TEGRA_HWPM_RESOURCE_MCF_IOBHX; + break; default: tegra_hwpm_err(hwpm, "Queried enum tegra_soc_hwpm_resource %d is invalid", diff --git a/include/uapi/linux/tegra-soc-hwpm-uapi.h b/include/uapi/linux/tegra-soc-hwpm-uapi.h index 0b430fa..e8f7c12 100644 --- a/include/uapi/linux/tegra-soc-hwpm-uapi.h +++ b/include/uapi/linux/tegra-soc-hwpm-uapi.h @@ -51,6 +51,8 @@ enum tegra_soc_hwpm_ip { TEGRA_SOC_HWPM_IP_NVLRX, TEGRA_SOC_HWPM_IP_NVLTX, TEGRA_SOC_HWPM_IP_MSS_HUB, + TEGRA_SOC_HWPM_IP_MCF_OCU, + TEGRA_SOC_HWPM_IP_MCF_IOBHX, TERGA_SOC_HWPM_NUM_IPS }; @@ -124,6 +126,8 @@ enum tegra_soc_hwpm_resource { TEGRA_SOC_HWPM_RESOURCE_NVLRX, TEGRA_SOC_HWPM_RESOURCE_NVLTX, TEGRA_SOC_HWPM_RESOURCE_MSS_HUB, + TEGRA_SOC_HWPM_RESOURCE_MCF_OCU, + TEGRA_SOC_HWPM_RESOURCE_MCF_IOBHX, TERGA_SOC_HWPM_NUM_RESOURCES };