diff --git a/drivers/tegra/hwpm/Kconfig b/drivers/tegra/hwpm/Kconfig index 025146e..3bed780 100644 --- a/drivers/tegra/hwpm/Kconfig +++ b/drivers/tegra/hwpm/Kconfig @@ -10,4 +10,11 @@ config TEGRA_T234_HWPM depends on TEGRA_SOC_HWPM && ARCH_TEGRA_23x_SOC default y if (TEGRA_SOC_HWPM && ARCH_TEGRA_23x_SOC) help - T23x performance monitoring driver. \ No newline at end of file + T23x performance monitoring driver. + +config TEGRA_TH500_HWPM + bool "Tegra TH500 HWPM driver" + depends on TEGRA_SOC_HWPM && ARCH_TEGRA_TH500_SOC + default y if (TEGRA_SOC_HWPM && ARCH_TEGRA_TH500_SOC) + help + TH500 performance monitoring driver. diff --git a/drivers/tegra/hwpm/Makefile b/drivers/tegra/hwpm/Makefile index 9b671ce..c9d67d9 100644 --- a/drivers/tegra/hwpm/Makefile +++ b/drivers/tegra/hwpm/Makefile @@ -10,12 +10,6 @@ ifeq ($(origin srctree.hwpm), undefined) srctree.hwpm := $(abspath $(shell dirname $(lastword $(MAKEFILE_LIST))))/../../.. endif -CONFIG_TEGRA_SOC_HWPM := y -ccflags-y += -DCONFIG_TEGRA_SOC_HWPM - -CONFIG_TEGRA_T234_HWPM := y -ccflags-y += -DCONFIG_TEGRA_T234_HWPM - # For OOT builds, set required config flags ifeq ($(CONFIG_TEGRA_OOT_MODULE),m) NVHWPM_OBJ = m @@ -26,6 +20,7 @@ ccflags-y += -DCONFIG_TEGRA_HWPM_OOT CONFIG_TEGRA_FUSE_UPSTREAM := y ccflags-y += -DCONFIG_TEGRA_FUSE_UPSTREAM + LINUXINCLUDE += -I$(srctree.nvconftest) LINUXINCLUDE += -I$(srctree.hwpm)/include LINUXINCLUDE += -I$(srctree.hwpm)/drivers/tegra/hwpm/include @@ -50,3 +45,10 @@ include $(srctree.hwpm)/drivers/tegra/hwpm/Makefile.hwpm.sources endif obj-${NVHWPM_OBJ} += nvhwpm.o + +all: + make -C /lib/modules/$(shell uname -r)/build M=$(PWD) $(ccflags) modules + +clean: + make -C /lib/modules/$(shell uname -r)/build M=$(PWD) clean + diff --git a/drivers/tegra/hwpm/Makefile.hwpm.sources b/drivers/tegra/hwpm/Makefile.hwpm.sources index 6439481..5f6e8f9 100644 --- a/drivers/tegra/hwpm/Makefile.hwpm.sources +++ b/drivers/tegra/hwpm/Makefile.hwpm.sources @@ -28,7 +28,7 @@ include ${srctree.hwpm-next}/drivers/tegra/Makefile.hwpm-next.sources nvhwpm-objs += ${nvhwpm-next-objs} endif -endif +endif # CONFIG_TEGRA_OOT_MODULE # Include common files include ${srctree.hwpm}/drivers/tegra/hwpm/Makefile.common.sources @@ -38,8 +38,27 @@ nvhwpm-objs += ${nvhwpm-common-objs} include ${srctree.hwpm}/drivers/tegra/hwpm/Makefile.linux.sources nvhwpm-objs += ${nvhwpm-linux-objs} +CONFIG_TEGRA_SOC_HWPM := y +ccflags-y += -DCONFIG_TEGRA_SOC_HWPM + +CONFIG_TEGRA_T234_HWPM := y +ccflags-y += -DCONFIG_TEGRA_T234_HWPM + ifeq ($(CONFIG_TEGRA_T234_HWPM),y) # Include T234 files include ${srctree.hwpm}/drivers/tegra/hwpm/Makefile.t234.sources nvhwpm-objs += ${nvhwpm-t234-objs} endif + +# TH500 HWPM is only supported with BaseOS as an OOT module. +ifeq ($(CONFIG_TEGRA_OOT_MODULE),m) # also check BaseOS build here +CONFIG_TEGRA_TH500_HWPM := y +ccflags-y += -DCONFIG_TEGRA_TH500_HWPM + +ifeq ($(CONFIG_TEGRA_TH500_HWPM),y) +# Include TH500 files +include ${srctree.hwpm}/drivers/tegra/hwpm/Makefile.th500.sources +nvhwpm-objs += ${nvhwpm-th500-objs} +endif + +endif # CONFIG_TEGRA_OOT_MODULE diff --git a/drivers/tegra/hwpm/Makefile.th500.soc.sources b/drivers/tegra/hwpm/Makefile.th500.soc.sources new file mode 100644 index 0000000..7d68fb7 --- /dev/null +++ b/drivers/tegra/hwpm/Makefile.th500.soc.sources @@ -0,0 +1,46 @@ +# +# Tegra SOC HWPM TH500 sources +# + +ifeq ($(CONFIG_TEGRA_TH500_HWPM),y) +nvhwpm-th500-soc-objs += hal/th500/soc/th500_soc_aperture.o +nvhwpm-th500-soc-objs += hal/th500/soc/th500_soc_mem_mgmt.o +nvhwpm-th500-soc-objs += hal/th500/soc/th500_soc_regops_allowlist.o +nvhwpm-th500-soc-objs += hal/th500/soc/th500_soc_resource.o + +# +# Control IP config +# To disable an IP config in compilation, add condition for both +# IP config flag and IP specific .o file. +# + +# +# RTR/PMA are HWPM IPs and can be enabled by default +# +nvhwpm-th500-soc-objs += hal/th500/soc/ip/rtr/th500_rtr.o +nvhwpm-th500-soc-objs += hal/th500/soc/ip/pma/th500_pma.o + +# +# One of the HWPM components is a perfmux. Perfmux registers belong to the +# IP domain. There are 2 ways of accessing perfmux registers +# - option 1: implement HWPM <-> IP interface. IP drivers register with HWPM +# driver and share required function pointers +# - option 2: map perfmux register address in HWPM driver +# Option 1 is a preferred solution. However, IP drivers have yet to +# implement the interface. Such IPs can be force enabled from HWPM driver +# perspective. However, forcing an IP will enable all instances of the IP. +# Hence, IP force enable should only be done on full chip config. +# Note as power management API is not available, unpowergating the IP via +# command line is required. +# +# Enable CONFIG_TH500_HWPM_ALLOW_FORCE_ENABLE as required +# +ccflags-y += -DCONFIG_TH500_HWPM_ALLOW_FORCE_ENABLE + +ccflags-y += -DCONFIG_TH500_HWPM_IP_MSS_CHANNEL +nvhwpm-th500-soc-objs += hal/th500/soc/ip/mss_channel/th500_mss_channel.o + +ccflags-y += -DCONFIG_TH500_HWPM_IP_C2C +nvhwpm-th500-objs += hal/th500/soc/ip/c2c/th500_c2c.o + +endif diff --git a/drivers/tegra/hwpm/Makefile.th500.sources b/drivers/tegra/hwpm/Makefile.th500.sources new file mode 100644 index 0000000..f7fea36 --- /dev/null +++ b/drivers/tegra/hwpm/Makefile.th500.sources @@ -0,0 +1,19 @@ +# +# Tegra SOC HWPM TH500 sources +# + +ifeq ($(CONFIG_TEGRA_TH500_HWPM),y) +nvhwpm-th500-objs += hal/th500/th500_interface.o +nvhwpm-th500-objs += hal/th500/th500_ip.o + +# Include TH500 SOC files +include $(srctree.hwpm)/drivers/tegra/hwpm/Makefile.th500.soc.sources +nvhwpm-th500-objs += $(nvhwpm-th500-soc-objs) + +# Include TH500 CCPLEX files +ifneq ($(wildcard $(srctree.hwpm)/drivers/tegra/hwpm/Makefile.th500.ccplex.sources),) +$(info "--------------Makefile.th500.ccplex.sources available") +include $(srctree.hwpm)/drivers/tegra/hwpm/Makefile.th500.ccplex.sources +nvhwpm-th500-objs += $(nvhwpm-th500-ccplex-objs) +endif +endif diff --git a/drivers/tegra/hwpm/common/init.c b/drivers/tegra/hwpm/common/init.c index 14de9d8..5871d83 100644 --- a/drivers/tegra/hwpm/common/init.c +++ b/drivers/tegra/hwpm/common/init.c @@ -30,13 +30,11 @@ #include #include +#include #ifdef CONFIG_TEGRA_NEXT1_HWPM #include #endif -#ifdef CONFIG_TEGRA_NEXT2_HWPM -#include -#endif #ifdef CONFIG_TEGRA_NEXT3_HWPM #include #endif @@ -65,16 +63,20 @@ static int tegra_hwpm_init_chip_ip_structures(struct tegra_soc_hwpm *hwpm, break; } break; - default: -#if defined(CONFIG_TEGRA_NEXT2_HWPM) - err = tegra_hwpm_next2_init_chip_ip_structures( - hwpm, chip_id, chip_id_rev); - if (err == 0) { - /* Execution is for NEXT2 chip */ +#ifdef CONFIG_TEGRA_TH500_HWPM + case 0x50: + switch (chip_id_rev) { + case 0x0: + err = th500_hwpm_init_chip_info(hwpm); + break; + default: + tegra_hwpm_err(hwpm, "Chip 0x%x rev 0x%x not supported", + chip_id, chip_id_rev); break; } + break; #endif - + default: #if defined(CONFIG_TEGRA_NEXT3_HWPM) err = tegra_hwpm_next3_init_chip_ip_structures( hwpm, chip_id, chip_id_rev); @@ -84,7 +86,7 @@ static int tegra_hwpm_init_chip_ip_structures(struct tegra_soc_hwpm *hwpm, } #endif -#if !defined(CONFIG_TEGRA_NEXT2_HWPM) && !defined(CONFIG_TEGRA_NEXT3_HWPM) +#if !defined(CONFIG_TEGRA_NEXT3_HWPM) tegra_hwpm_err(hwpm, "Chip 0x%x not supported", chip_id); #endif break; diff --git a/drivers/tegra/hwpm/hal/th500/soc/hw/th500_addr_map_soc_hwpm.h b/drivers/tegra/hwpm/hal/th500/soc/hw/th500_addr_map_soc_hwpm.h new file mode 100644 index 0000000..778a7e8 --- /dev/null +++ b/drivers/tegra/hwpm/hal/th500/soc/hw/th500_addr_map_soc_hwpm.h @@ -0,0 +1,478 @@ +/* + * Copyright (c) 2022-2023, NVIDIA CORPORATION. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ +/* + * Function/Macro naming determines intended use: + * + * _r(void) : Returns the offset for register . + * + * _o(void) : Returns the offset for element . + * + * _w(void) : Returns the word offset for word (4 byte) element . + * + * __s(void) : Returns size of field of register in bits. + * + * __f(u32 v) : Returns a value based on 'v' which has been shifted + * and masked to place it at field of register . This value + * can be |'d with others to produce a full register value for + * register . + * + * __m(void) : Returns a mask for field of register . This + * value can be ~'d and then &'d to clear the value of field for + * register . + * + * ___f(void) : Returns the constant value after being shifted + * to place it at field of register . This value can be |'d + * with others to produce a full register value for . + * + * __v(u32 r) : Returns the value of field from a full register + * value 'r' after being shifted to place its LSB at bit 0. + * This value is suitable for direct comparison with other unshifted + * values appropriate for use in field of register . + * + * ___v(void) : Returns the constant value for defined for + * field of register . This value is suitable for direct + * comparison with unshifted values appropriate for use in field + * of register . + */ +#ifndef TH500_ADDR_MAP_SOC_HWPM_H +#define TH500_ADDR_MAP_SOC_HWPM_H + +#define addr_map_rpg_pm_base_r() (0x13e00000U) +#define addr_map_rpg_pm_limit_r() (0x13eeffffU) +#define addr_map_rpg_pm_sys0_base_r() (0x13e1e000U) +#define addr_map_rpg_pm_sys0_limit_r() (0x13e1efffU) +#define addr_map_pma_base_r() (0x13ef0000U) +#define addr_map_pma_limit_r() (0x13ef1fffU) +#define addr_map_rtr_base_r() (0x13ef2000U) +#define addr_map_rtr_limit_r() (0x13ef2fffU) +#define addr_map_rpg_pm_msschannel0_base_r() (0x13e1f000U) +#define addr_map_rpg_pm_msschannel0_limit_r() (0x13e1ffffU) +#define addr_map_rpg_pm_msschannel1_base_r() (0x13e20000U) +#define addr_map_rpg_pm_msschannel1_limit_r() (0x13e20fffU) +#define addr_map_rpg_pm_msschannel2_base_r() (0x13e21000U) +#define addr_map_rpg_pm_msschannel2_limit_r() (0x13e21fffU) +#define addr_map_rpg_pm_msschannel3_base_r() (0x13e22000U) +#define addr_map_rpg_pm_msschannel3_limit_r() (0x13e22fffU) +#define addr_map_rpg_pm_msschannel4_base_r() (0x13e23000U) +#define addr_map_rpg_pm_msschannel4_limit_r() (0x13e23fffU) +#define addr_map_rpg_pm_msschannel5_base_r() (0x13e24000U) +#define addr_map_rpg_pm_msschannel5_limit_r() (0x13e24fffU) +#define addr_map_rpg_pm_msschannel6_base_r() (0x13e25000U) +#define addr_map_rpg_pm_msschannel6_limit_r() (0x13e25fffU) +#define addr_map_rpg_pm_msschannel7_base_r() (0x13e26000U) +#define addr_map_rpg_pm_msschannel7_limit_r() (0x13e26fffU) +#define addr_map_rpg_pm_msschannel8_base_r() (0x13e27000U) +#define addr_map_rpg_pm_msschannel8_limit_r() (0x13e27fffU) +#define addr_map_rpg_pm_msschannel9_base_r() (0x13e28000U) +#define addr_map_rpg_pm_msschannel9_limit_r() (0x13e28fffU) +#define addr_map_rpg_pm_msschannel10_base_r() (0x13e29000U) +#define addr_map_rpg_pm_msschannel10_limit_r() (0x13e29fffU) +#define addr_map_rpg_pm_msschannel11_base_r() (0x13e2a000U) +#define addr_map_rpg_pm_msschannel11_limit_r() (0x13e2afffU) +#define addr_map_rpg_pm_msschannel12_base_r() (0x13e2b000U) +#define addr_map_rpg_pm_msschannel12_limit_r() (0x13e2bfffU) +#define addr_map_rpg_pm_msschannel13_base_r() (0x13e2c000U) +#define addr_map_rpg_pm_msschannel13_limit_r() (0x13e2cfffU) +#define addr_map_rpg_pm_msschannel14_base_r() (0x13e2d000U) +#define addr_map_rpg_pm_msschannel14_limit_r() (0x13e2dfffU) +#define addr_map_rpg_pm_msschannel15_base_r() (0x13e2e000U) +#define addr_map_rpg_pm_msschannel15_limit_r() (0x13e2efffU) +#define addr_map_rpg_pm_msschannel16_base_r() (0x13e2f000U) +#define addr_map_rpg_pm_msschannel16_limit_r() (0x13e2ffffU) +#define addr_map_rpg_pm_msschannel17_base_r() (0x13e30000U) +#define addr_map_rpg_pm_msschannel17_limit_r() (0x13e30fffU) +#define addr_map_rpg_pm_msschannel18_base_r() (0x13e31000U) +#define addr_map_rpg_pm_msschannel18_limit_r() (0x13e31fffU) +#define addr_map_rpg_pm_msschannel19_base_r() (0x13e32000U) +#define addr_map_rpg_pm_msschannel19_limit_r() (0x13e32fffU) +#define addr_map_rpg_pm_msschannel20_base_r() (0x13e33000U) +#define addr_map_rpg_pm_msschannel20_limit_r() (0x13e33fffU) +#define addr_map_rpg_pm_msschannel21_base_r() (0x13e34000U) +#define addr_map_rpg_pm_msschannel21_limit_r() (0x13e34fffU) +#define addr_map_rpg_pm_msschannel22_base_r() (0x13e35000U) +#define addr_map_rpg_pm_msschannel22_limit_r() (0x13e35fffU) +#define addr_map_rpg_pm_msschannel23_base_r() (0x13e36000U) +#define addr_map_rpg_pm_msschannel23_limit_r() (0x13e36fffU) +#define addr_map_rpg_pm_msschannel24_base_r() (0x13e37000U) +#define addr_map_rpg_pm_msschannel24_limit_r() (0x13e37fffU) +#define addr_map_rpg_pm_msschannel25_base_r() (0x13e38000U) +#define addr_map_rpg_pm_msschannel25_limit_r() (0x13e38fffU) +#define addr_map_rpg_pm_msschannel26_base_r() (0x13e39000U) +#define addr_map_rpg_pm_msschannel26_limit_r() (0x13e39fffU) +#define addr_map_rpg_pm_msschannel27_base_r() (0x13e3a000U) +#define addr_map_rpg_pm_msschannel27_limit_r() (0x13e3afffU) +#define addr_map_rpg_pm_msschannel28_base_r() (0x13e3b000U) +#define addr_map_rpg_pm_msschannel28_limit_r() (0x13e3bfffU) +#define addr_map_rpg_pm_msschannel29_base_r() (0x13e3c000U) +#define addr_map_rpg_pm_msschannel29_limit_r() (0x13e3cfffU) +#define addr_map_rpg_pm_msschannel30_base_r() (0x13e3d000U) +#define addr_map_rpg_pm_msschannel30_limit_r() (0x13e3dfffU) +#define addr_map_rpg_pm_msschannel31_base_r() (0x13e3e000U) +#define addr_map_rpg_pm_msschannel31_limit_r() (0x13e3efffU) +#define addr_map_mcb_base_r() (0x04020000U) +#define addr_map_mcb_limit_r() (0x0403ffffU) +#define addr_map_mc0_base_r() (0x04040000U) +#define addr_map_mc0_limit_r() (0x0405ffffU) +#define addr_map_mc1_base_r() (0x04060000U) +#define addr_map_mc1_limit_r() (0x0407ffffU) +#define addr_map_mc2_base_r() (0x04080000U) +#define addr_map_mc2_limit_r() (0x0409ffffU) +#define addr_map_mc3_base_r() (0x040a0000U) +#define addr_map_mc3_limit_r() (0x040bffffU) +#define addr_map_mc4_base_r() (0x040c0000U) +#define addr_map_mc4_limit_r() (0x040dffffU) +#define addr_map_mc5_base_r() (0x040e0000U) +#define addr_map_mc5_limit_r() (0x040fffffU) +#define addr_map_mc6_base_r() (0x04100000U) +#define addr_map_mc6_limit_r() (0x0411ffffU) +#define addr_map_mc7_base_r() (0x04120000U) +#define addr_map_mc7_limit_r() (0x0413ffffU) +#define addr_map_mc8_base_r() (0x04140000U) +#define addr_map_mc8_limit_r() (0x0415ffffU) +#define addr_map_mc9_base_r() (0x04160000U) +#define addr_map_mc9_limit_r() (0x0417ffffU) +#define addr_map_mc10_base_r() (0x04180000U) +#define addr_map_mc10_limit_r() (0x0419ffffU) +#define addr_map_mc11_base_r() (0x041a0000U) +#define addr_map_mc11_limit_r() (0x041bffffU) +#define addr_map_mc12_base_r() (0x041c0000U) +#define addr_map_mc12_limit_r() (0x041dffffU) +#define addr_map_mc13_base_r() (0x041e0000U) +#define addr_map_mc13_limit_r() (0x041fffffU) +#define addr_map_mc14_base_r() (0x04200000U) +#define addr_map_mc14_limit_r() (0x0421ffffU) +#define addr_map_mc15_base_r() (0x04220000U) +#define addr_map_mc15_limit_r() (0x0423ffffU) +#define addr_map_mc16_base_r() (0x04240000U) +#define addr_map_mc16_limit_r() (0x0425ffffU) +#define addr_map_mc17_base_r() (0x04260000U) +#define addr_map_mc17_limit_r() (0x0427ffffU) +#define addr_map_mc18_base_r() (0x04280000U) +#define addr_map_mc18_limit_r() (0x0429ffffU) +#define addr_map_mc19_base_r() (0x042a0000U) +#define addr_map_mc19_limit_r() (0x042bffffU) +#define addr_map_mc20_base_r() (0x042c0000U) +#define addr_map_mc20_limit_r() (0x042dffffU) +#define addr_map_mc21_base_r() (0x042e0000U) +#define addr_map_mc21_limit_r() (0x042fffffU) +#define addr_map_mc22_base_r() (0x04300000U) +#define addr_map_mc22_limit_r() (0x0431ffffU) +#define addr_map_mc23_base_r() (0x04320000U) +#define addr_map_mc23_limit_r() (0x0433ffffU) +#define addr_map_mc24_base_r() (0x04340000U) +#define addr_map_mc24_limit_r() (0x0435ffffU) +#define addr_map_mc25_base_r() (0x04360000U) +#define addr_map_mc25_limit_r() (0x0437ffffU) +#define addr_map_mc26_base_r() (0x04380000U) +#define addr_map_mc26_limit_r() (0x0439ffffU) +#define addr_map_mc27_base_r() (0x043a0000U) +#define addr_map_mc27_limit_r() (0x043bffffU) +#define addr_map_mc28_base_r() (0x043c0000U) +#define addr_map_mc28_limit_r() (0x043dffffU) +#define addr_map_mc29_base_r() (0x043e0000U) +#define addr_map_mc29_limit_r() (0x043fffffU) +#define addr_map_mc30_base_r() (0x04400000U) +#define addr_map_mc30_limit_r() (0x0441ffffU) +#define addr_map_mc31_base_r() (0x04420000U) +#define addr_map_mc31_limit_r() (0x0443ffffU) +#define addr_map_rpg_pm_lts0_base_r() (0x13e3f000U) +#define addr_map_rpg_pm_lts0_limit_r() (0x13e3ffffU) +#define addr_map_rpg_pm_lts1_base_r() (0x13e40000U) +#define addr_map_rpg_pm_lts1_limit_r() (0x13e40fffU) +#define addr_map_rpg_pm_lts2_base_r() (0x13e41000U) +#define addr_map_rpg_pm_lts2_limit_r() (0x13e41fffU) +#define addr_map_rpg_pm_lts3_base_r() (0x13e42000U) +#define addr_map_rpg_pm_lts3_limit_r() (0x13e42fffU) +#define addr_map_rpg_pm_lts4_base_r() (0x13e43000U) +#define addr_map_rpg_pm_lts4_limit_r() (0x13e43fffU) +#define addr_map_rpg_pm_lts5_base_r() (0x13e44000U) +#define addr_map_rpg_pm_lts5_limit_r() (0x13e44fffU) +#define addr_map_rpg_pm_lts6_base_r() (0x13e45000U) +#define addr_map_rpg_pm_lts6_limit_r() (0x13e45fffU) +#define addr_map_rpg_pm_lts7_base_r() (0x13e46000U) +#define addr_map_rpg_pm_lts7_limit_r() (0x13e46fffU) +#define addr_map_rpg_pm_lts8_base_r() (0x13e47000U) +#define addr_map_rpg_pm_lts8_limit_r() (0x13e47fffU) +#define addr_map_rpg_pm_lts9_base_r() (0x13e48000U) +#define addr_map_rpg_pm_lts9_limit_r() (0x13e48fffU) +#define addr_map_rpg_pm_lts10_base_r() (0x13e49000U) +#define addr_map_rpg_pm_lts10_limit_r() (0x13e49fffU) +#define addr_map_rpg_pm_lts11_base_r() (0x13e4a000U) +#define addr_map_rpg_pm_lts11_limit_r() (0x13e4afffU) +#define addr_map_rpg_pm_lts12_base_r() (0x13e4b000U) +#define addr_map_rpg_pm_lts12_limit_r() (0x13e4bfffU) +#define addr_map_rpg_pm_lts13_base_r() (0x13e4c000U) +#define addr_map_rpg_pm_lts13_limit_r() (0x13e4cfffU) +#define addr_map_rpg_pm_lts14_base_r() (0x13e4d000U) +#define addr_map_rpg_pm_lts14_limit_r() (0x13e4dfffU) +#define addr_map_rpg_pm_lts15_base_r() (0x13e4e000U) +#define addr_map_rpg_pm_lts15_limit_r() (0x13e4efffU) +#define addr_map_ltc0_base_r() (0x04e10000U) +#define addr_map_ltc0_limit_r() (0x04e1ffffU) +#define addr_map_ltc1_base_r() (0x04e20000U) +#define addr_map_ltc1_limit_r() (0x04e2ffffU) +#define addr_map_ltc2_base_r() (0x04e30000U) +#define addr_map_ltc2_limit_r() (0x04e3ffffU) +#define addr_map_ltc3_base_r() (0x04e40000U) +#define addr_map_ltc3_limit_r() (0x04e4ffffU) +#define addr_map_ltc4_base_r() (0x04e50000U) +#define addr_map_ltc4_limit_r() (0x04e5ffffU) +#define addr_map_ltc5_base_r() (0x04e60000U) +#define addr_map_ltc5_limit_r() (0x04e6ffffU) +#define addr_map_ltc6_base_r() (0x04e70000U) +#define addr_map_ltc6_limit_r() (0x04e7ffffU) +#define addr_map_ltc7_base_r() (0x04e80000U) +#define addr_map_ltc7_limit_r() (0x04e8ffffU) +#define addr_map_rpg_pm_mcfcore0_base_r() (0x13e4f000U) +#define addr_map_rpg_pm_mcfcore0_limit_r() (0x13e4ffffU) +#define addr_map_rpg_pm_mcfcore1_base_r() (0x13e50000U) +#define addr_map_rpg_pm_mcfcore1_limit_r() (0x13e50fffU) +#define addr_map_rpg_pm_mcfcore2_base_r() (0x13e51000U) +#define addr_map_rpg_pm_mcfcore2_limit_r() (0x13e51fffU) +#define addr_map_rpg_pm_mcfcore3_base_r() (0x13e52000U) +#define addr_map_rpg_pm_mcfcore3_limit_r() (0x13e52fffU) +#define addr_map_rpg_pm_mcfcore4_base_r() (0x13e53000U) +#define addr_map_rpg_pm_mcfcore4_limit_r() (0x13e53fffU) +#define addr_map_rpg_pm_mcfcore5_base_r() (0x13e54000U) +#define addr_map_rpg_pm_mcfcore5_limit_r() (0x13e54fffU) +#define addr_map_rpg_pm_mcfcore6_base_r() (0x13e55000U) +#define addr_map_rpg_pm_mcfcore6_limit_r() (0x13e55fffU) +#define addr_map_rpg_pm_mcfcore7_base_r() (0x13e56000U) +#define addr_map_rpg_pm_mcfcore7_limit_r() (0x13e56fffU) +#define addr_map_rpg_pm_mcfcore8_base_r() (0x13e57000U) +#define addr_map_rpg_pm_mcfcore8_limit_r() (0x13e57fffU) +#define addr_map_rpg_pm_mcfcore9_base_r() (0x13e58000U) +#define addr_map_rpg_pm_mcfcore9_limit_r() (0x13e58fffU) +#define addr_map_rpg_pm_mcfcore10_base_r() (0x13e59000U) +#define addr_map_rpg_pm_mcfcore10_limit_r() (0x13e59fffU) +#define addr_map_rpg_pm_mcfcore11_base_r() (0x13e5a000U) +#define addr_map_rpg_pm_mcfcore11_limit_r() (0x13e5afffU) +#define addr_map_rpg_pm_mcfcore12_base_r() (0x13e5b000U) +#define addr_map_rpg_pm_mcfcore12_limit_r() (0x13e5bfffU) +#define addr_map_rpg_pm_mcfcore13_base_r() (0x13e5c000U) +#define addr_map_rpg_pm_mcfcore13_limit_r() (0x13e5cfffU) +#define addr_map_rpg_pm_mcfcore14_base_r() (0x13e5d000U) +#define addr_map_rpg_pm_mcfcore14_limit_r() (0x13e5dfffU) +#define addr_map_rpg_pm_mcfcore15_base_r() (0x13e5e000U) +#define addr_map_rpg_pm_mcfcore15_limit_r() (0x13e5efffU) +#define addr_map_rpg_pm_mcfsys0_base_r() (0x13e5f000U) +#define addr_map_rpg_pm_mcfsys0_limit_r() (0x13e5ffffU) +#define addr_map_rpg_pm_mcfsys1_base_r() (0x13e60000U) +#define addr_map_rpg_pm_mcfsys1_limit_r() (0x13e60fffU) +#define addr_map_rpg_pm_mcfctc0_base_r() (0x13e61000U) +#define addr_map_rpg_pm_mcfctc0_limit_r() (0x13e61fffU) +#define addr_map_rpg_pm_mcfctc1_base_r() (0x13e62000U) +#define addr_map_rpg_pm_mcfctc1_limit_r() (0x13e62fffU) +#define addr_map_rpg_pm_mcfsoc0_base_r() (0x13e63000U) +#define addr_map_rpg_pm_mcfsoc0_limit_r() (0x13e63fffU) +#define addr_map_rpg_pm_smmu0_base_r() (0x13e64000U) +#define addr_map_rpg_pm_smmu0_limit_r() (0x13e64fffU) +#define addr_map_rpg_pm_smmu1_base_r() (0x13e65000U) +#define addr_map_rpg_pm_smmu1_limit_r() (0x13e65fffU) +#define addr_map_rpg_pm_smmu2_base_r() (0x13e66000U) +#define addr_map_rpg_pm_smmu2_limit_r() (0x13e66fffU) +#define addr_map_rpg_pm_smmu3_base_r() (0x13e67000U) +#define addr_map_rpg_pm_smmu3_limit_r() (0x13e67fffU) +#define addr_map_rpg_pm_smmu4_base_r() (0x13e68000U) +#define addr_map_rpg_pm_smmu4_limit_r() (0x13e68fffU) +#define addr_map_smmu0_base_r() (0x11000000U) +#define addr_map_smmu0_limit_r() (0x11ffffffU) +#define addr_map_smmu1_base_r() (0x12000000U) +#define addr_map_smmu1_limit_r() (0x12ffffffU) +#define addr_map_smmu2_base_r() (0x15000000U) +#define addr_map_smmu2_limit_r() (0x15ffffffU) +#define addr_map_rpg_pm_msshub0_base_r() (0x13e69000U) +#define addr_map_rpg_pm_msshub0_limit_r() (0x13e69fffU) +#define addr_map_rpg_pm_msshub1_base_r() (0x13e6a000U) +#define addr_map_rpg_pm_msshub1_limit_r() (0x13e6afffU) +#define addr_map_rpg_pm_msshub2_base_r() (0x13e6b000U) +#define addr_map_rpg_pm_msshub2_limit_r() (0x13e6bfffU) +#define addr_map_rpg_pm_msshub3_base_r() (0x13e6c000U) +#define addr_map_rpg_pm_msshub3_limit_r() (0x13e6cfffU) +#define addr_map_rpg_pm_msshub4_base_r() (0x13e6d000U) +#define addr_map_rpg_pm_msshub4_limit_r() (0x13e6dfffU) +#define addr_map_rpg_pm_msshub5_base_r() (0x13e6e000U) +#define addr_map_rpg_pm_msshub5_limit_r() (0x13e6efffU) +#define addr_map_rpg_pm_msshub6_base_r() (0x13e6f000U) +#define addr_map_rpg_pm_msshub6_limit_r() (0x13e6ffffU) +#define addr_map_rpg_pm_msshub7_base_r() (0x13e70000U) +#define addr_map_rpg_pm_msshub7_limit_r() (0x13e70fffU) +#define addr_map_rpg_pm_nvltx0_base_r() (0x13e71000U) +#define addr_map_rpg_pm_nvltx0_limit_r() (0x13e71fffU) +#define addr_map_rpg_pm_nvltx1_base_r() (0x13e72000U) +#define addr_map_rpg_pm_nvltx1_limit_r() (0x13e72fffU) +#define addr_map_rpg_pm_nvltx2_base_r() (0x13e73000U) +#define addr_map_rpg_pm_nvltx2_limit_r() (0x13e73fffU) +#define addr_map_rpg_pm_nvltx3_base_r() (0x13e74000U) +#define addr_map_rpg_pm_nvltx3_limit_r() (0x13e74fffU) +#define addr_map_rpg_pm_nvltx4_base_r() (0x13e75000U) +#define addr_map_rpg_pm_nvltx4_limit_r() (0x13e75fffU) +#define addr_map_rpg_pm_nvltx5_base_r() (0x13e76000U) +#define addr_map_rpg_pm_nvltx5_limit_r() (0x13e76fffU) +#define addr_map_rpg_pm_nvltx6_base_r() (0x13e77000U) +#define addr_map_rpg_pm_nvltx6_limit_r() (0x13e77fffU) +#define addr_map_rpg_pm_nvltx7_base_r() (0x13e78000U) +#define addr_map_rpg_pm_nvltx7_limit_r() (0x13e78fffU) +#define addr_map_rpg_pm_nvltx8_base_r() (0x13e79000U) +#define addr_map_rpg_pm_nvltx8_limit_r() (0x13e79fffU) +#define addr_map_rpg_pm_nvltx9_base_r() (0x13e7a000U) +#define addr_map_rpg_pm_nvltx9_limit_r() (0x13e7afffU) +#define addr_map_rpg_pm_nvltx10_base_r() (0x13e7b000U) +#define addr_map_rpg_pm_nvltx10_limit_r() (0x13e7bfffU) +#define addr_map_rpg_pm_nvltx11_base_r() (0x13e7c000U) +#define addr_map_rpg_pm_nvltx11_limit_r() (0x13e7cfffU) +#define addr_map_rpg_pm_nvlrx0_base_r() (0x13e7d000U) +#define addr_map_rpg_pm_nvlrx0_limit_r() (0x13e7dfffU) +#define addr_map_rpg_pm_nvlrx1_base_r() (0x13e7e000U) +#define addr_map_rpg_pm_nvlrx1_limit_r() (0x13e7efffU) +#define addr_map_rpg_pm_nvlrx2_base_r() (0x13e7f000U) +#define addr_map_rpg_pm_nvlrx2_limit_r() (0x13e7ffffU) +#define addr_map_rpg_pm_nvlrx3_base_r() (0x13e80000U) +#define addr_map_rpg_pm_nvlrx3_limit_r() (0x13e80fffU) +#define addr_map_rpg_pm_nvlrx4_base_r() (0x13e81000U) +#define addr_map_rpg_pm_nvlrx4_limit_r() (0x13e81fffU) +#define addr_map_rpg_pm_nvlrx5_base_r() (0x13e82000U) +#define addr_map_rpg_pm_nvlrx5_limit_r() (0x13e82fffU) +#define addr_map_rpg_pm_nvlrx6_base_r() (0x13e83000U) +#define addr_map_rpg_pm_nvlrx6_limit_r() (0x13e83fffU) +#define addr_map_rpg_pm_nvlrx7_base_r() (0x13e84000U) +#define addr_map_rpg_pm_nvlrx7_limit_r() (0x13e84fffU) +#define addr_map_rpg_pm_nvlrx8_base_r() (0x13e85000U) +#define addr_map_rpg_pm_nvlrx8_limit_r() (0x13e85fffU) +#define addr_map_rpg_pm_nvlrx9_base_r() (0x13e86000U) +#define addr_map_rpg_pm_nvlrx9_limit_r() (0x13e86fffU) +#define addr_map_rpg_pm_nvlrx10_base_r() (0x13e87000U) +#define addr_map_rpg_pm_nvlrx10_limit_r() (0x13e87fffU) +#define addr_map_rpg_pm_nvlrx11_base_r() (0x13e88000U) +#define addr_map_rpg_pm_nvlrx11_limit_r() (0x13e88fffU) +#define addr_map_rpg_pm_nvlctrl0_base_r() (0x13e8b000U) +#define addr_map_rpg_pm_nvlctrl0_limit_r() (0x13e8bfffU) +#define addr_map_rpg_pm_nvlctrl1_base_r() (0x13e8c000U) +#define addr_map_rpg_pm_nvlctrl1_limit_r() (0x13e8cfffU) +#define addr_map_nvlw0_base_r() (0x03b80000U) +#define addr_map_nvlw0_limit_r() (0x03bbffffU) +#define addr_map_nvlw1_base_r() (0x03bc0000U) +#define addr_map_nvlw1_limit_r() (0x03bfffffU) +#define addr_map_rpg_pm_xalrc0_base_r() (0x13e00000U) +#define addr_map_rpg_pm_xalrc0_limit_r() (0x13e00fffU) +#define addr_map_rpg_pm_xalrc1_base_r() (0x13e01000U) +#define addr_map_rpg_pm_xalrc1_limit_r() (0x13e01fffU) +#define addr_map_rpg_pm_xalrc2_base_r() (0x13e02000U) +#define addr_map_rpg_pm_xalrc2_limit_r() (0x13e02fffU) +#define addr_map_rpg_pm_xalrc3_base_r() (0x13e03000U) +#define addr_map_rpg_pm_xalrc3_limit_r() (0x13e03fffU) +#define addr_map_rpg_pm_xalrc4_base_r() (0x13e04000U) +#define addr_map_rpg_pm_xalrc4_limit_r() (0x13e04fffU) +#define addr_map_rpg_pm_xalrc5_base_r() (0x13e05000U) +#define addr_map_rpg_pm_xalrc5_limit_r() (0x13e05fffU) +#define addr_map_rpg_pm_xalrc6_base_r() (0x13e06000U) +#define addr_map_rpg_pm_xalrc6_limit_r() (0x13e06fffU) +#define addr_map_rpg_pm_xalrc7_base_r() (0x13e07000U) +#define addr_map_rpg_pm_xalrc7_limit_r() (0x13e07fffU) +#define addr_map_rpg_pm_xalrc8_base_r() (0x13e08000U) +#define addr_map_rpg_pm_xalrc8_limit_r() (0x13e08fffU) +#define addr_map_rpg_pm_xalrc9_base_r() (0x13e09000U) +#define addr_map_rpg_pm_xalrc9_limit_r() (0x13e09fffU) +#define addr_map_rpg_pm_xtlrc0_base_r() (0x13e0a000U) +#define addr_map_rpg_pm_xtlrc0_limit_r() (0x13e0afffU) +#define addr_map_rpg_pm_xtlrc1_base_r() (0x13e0b000U) +#define addr_map_rpg_pm_xtlrc1_limit_r() (0x13e0bfffU) +#define addr_map_rpg_pm_xtlrc2_base_r() (0x13e0c000U) +#define addr_map_rpg_pm_xtlrc2_limit_r() (0x13e0cfffU) +#define addr_map_rpg_pm_xtlrc3_base_r() (0x13e0d000U) +#define addr_map_rpg_pm_xtlrc3_limit_r() (0x13e0dfffU) +#define addr_map_rpg_pm_xtlrc4_base_r() (0x13e0e000U) +#define addr_map_rpg_pm_xtlrc4_limit_r() (0x13e0efffU) +#define addr_map_rpg_pm_xtlrc5_base_r() (0x13e0f000U) +#define addr_map_rpg_pm_xtlrc5_limit_r() (0x13e0ffffU) +#define addr_map_rpg_pm_xtlrc6_base_r() (0x13e10000U) +#define addr_map_rpg_pm_xtlrc6_limit_r() (0x13e10fffU) +#define addr_map_rpg_pm_xtlrc7_base_r() (0x13e11000U) +#define addr_map_rpg_pm_xtlrc7_limit_r() (0x13e11fffU) +#define addr_map_rpg_pm_xtlrc8_base_r() (0x13e12000U) +#define addr_map_rpg_pm_xtlrc8_limit_r() (0x13e12fffU) +#define addr_map_rpg_pm_xtlrc9_base_r() (0x13e13000U) +#define addr_map_rpg_pm_xtlrc9_limit_r() (0x13e13fffU) +#define addr_map_rpg_pm_xtlq0_base_r() (0x13e14000U) +#define addr_map_rpg_pm_xtlq0_limit_r() (0x13e14fffU) +#define addr_map_rpg_pm_xtlq1_base_r() (0x13e15000U) +#define addr_map_rpg_pm_xtlq1_limit_r() (0x13e15fffU) +#define addr_map_rpg_pm_xtlq2_base_r() (0x13e16000U) +#define addr_map_rpg_pm_xtlq2_limit_r() (0x13e16fffU) +#define addr_map_rpg_pm_xtlq3_base_r() (0x13e17000U) +#define addr_map_rpg_pm_xtlq3_limit_r() (0x13e17fffU) +#define addr_map_rpg_pm_xtlq4_base_r() (0x13e18000U) +#define addr_map_rpg_pm_xtlq4_limit_r() (0x13e18fffU) +#define addr_map_rpg_pm_xtlq5_base_r() (0x13e19000U) +#define addr_map_rpg_pm_xtlq5_limit_r() (0x13e19fffU) +#define addr_map_rpg_pm_xtlq6_base_r() (0x13e1a000U) +#define addr_map_rpg_pm_xtlq6_limit_r() (0x13e1afffU) +#define addr_map_rpg_pm_xtlq7_base_r() (0x13e1b000U) +#define addr_map_rpg_pm_xtlq7_limit_r() (0x13e1bfffU) +#define addr_map_rpg_pm_xtlq8_base_r() (0x13e1c000U) +#define addr_map_rpg_pm_xtlq8_limit_r() (0x13e1cfffU) +#define addr_map_rpg_pm_xtlq9_base_r() (0x13e1d000U) +#define addr_map_rpg_pm_xtlq9_limit_r() (0x13e1dfffU) +#define addr_map_pcie_c0_ctl0_base_r() (0x14080000U) +#define addr_map_pcie_c0_ctl0_limit_r() (0x1408ffffU) +#define addr_map_pcie_c1_ctl0_base_r() (0x140a0000U) +#define addr_map_pcie_c1_ctl0_limit_r() (0x140affffU) +#define addr_map_pcie_c2_ctl0_base_r() (0x140c0000U) +#define addr_map_pcie_c2_ctl0_limit_r() (0x140cffffU) +#define addr_map_pcie_c3_ctl0_base_r() (0x140e0000U) +#define addr_map_pcie_c3_ctl0_limit_r() (0x140effffU) +#define addr_map_pcie_c4_ctl0_base_r() (0x14100000U) +#define addr_map_pcie_c4_ctl0_limit_r() (0x1410ffffU) +#define addr_map_pcie_c5_ctl0_base_r() (0x14120000U) +#define addr_map_pcie_c5_ctl0_limit_r() (0x1412ffffU) +#define addr_map_pcie_c6_ctl0_base_r() (0x14140000U) +#define addr_map_pcie_c6_ctl0_limit_r() (0x1414ffffU) +#define addr_map_pcie_c7_ctl0_base_r() (0x14160000U) +#define addr_map_pcie_c7_ctl0_limit_r() (0x1416ffffU) +#define addr_map_pcie_c8_ctl0_base_r() (0x14180000U) +#define addr_map_pcie_c8_ctl0_limit_r() (0x1418ffffU) +#define addr_map_pcie_c9_ctl0_base_r() (0x141a0000U) +#define addr_map_pcie_c9_ctl0_limit_r() (0x141affffU) +#define addr_map_rpg_pm_ctc0_base_r() (0x13e8d000U) +#define addr_map_rpg_pm_ctc0_limit_r() (0x13e8dfffU) +#define addr_map_rpg_pm_ctc1_base_r() (0x13e8e000U) +#define addr_map_rpg_pm_ctc1_limit_r() (0x13e8efffU) +#define addr_map_c2c0_base_r() (0x13fe2000U) +#define addr_map_c2c0_limit_r() (0x13fe2fffU) +#define addr_map_c2c1_base_r() (0x13fe3000U) +#define addr_map_c2c1_limit_r() (0x13fe3fffU) +#define addr_map_c2c2_base_r() (0x13fe4000U) +#define addr_map_c2c2_limit_r() (0x13fe4fffU) +#define addr_map_c2c3_base_r() (0x13fe5000U) +#define addr_map_c2c3_limit_r() (0x13fe5fffU) +#define addr_map_c2c4_base_r() (0x13fe6000U) +#define addr_map_c2c4_limit_r() (0x13fe6fffU) +#define addr_map_c2c5_base_r() (0x13fe7000U) +#define addr_map_c2c5_limit_r() (0x13fe7fffU) +#define addr_map_c2c6_base_r() (0x13fe8000U) +#define addr_map_c2c6_limit_r() (0x13fe8fffU) +#define addr_map_c2c7_base_r() (0x13fe9000U) +#define addr_map_c2c7_limit_r() (0x13fe9fffU) +#define addr_map_c2c8_base_r() (0x13fea000U) +#define addr_map_c2c8_limit_r() (0x13feafffU) +#define addr_map_c2c9_base_r() (0x13feb000U) +#define addr_map_c2c9_limit_r() (0x13febfffU) +#define addr_map_c2cs0_base_r() (0x13fe0000U) +#define addr_map_c2cs0_limit_r() (0x13fe0fffU) +#define addr_map_c2cs1_base_r() (0x13fe1000U) +#define addr_map_c2cs1_limit_r() (0x13fe1fffU) +#define addr_map_pmc_misc_base_r() (0x0c3a0000U) +#endif diff --git a/drivers/tegra/hwpm/hal/th500/soc/hw/th500_pmasys_soc_hwpm.h b/drivers/tegra/hwpm/hal/th500/soc/hw/th500_pmasys_soc_hwpm.h new file mode 100644 index 0000000..bdbe527 --- /dev/null +++ b/drivers/tegra/hwpm/hal/th500/soc/hw/th500_pmasys_soc_hwpm.h @@ -0,0 +1,147 @@ +/* + * Copyright (c) 2022-2023, NVIDIA CORPORATION. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ +/* + * Function/Macro naming determines intended use: + * + * _r(void) : Returns the offset for register . + * + * _o(void) : Returns the offset for element . + * + * _w(void) : Returns the word offset for word (4 byte) element . + * + * __s(void) : Returns size of field of register in bits. + * + * __f(u32 v) : Returns a value based on 'v' which has been shifted + * and masked to place it at field of register . This value + * can be |'d with others to produce a full register value for + * register . + * + * __m(void) : Returns a mask for field of register . This + * value can be ~'d and then &'d to clear the value of field for + * register . + * + * ___f(void) : Returns the constant value after being shifted + * to place it at field of register . This value can be |'d + * with others to produce a full register value for . + * + * __v(u32 r) : Returns the value of field from a full register + * value 'r' after being shifted to place its LSB at bit 0. + * This value is suitable for direct comparison with other unshifted + * values appropriate for use in field of register . + * + * ___v(void) : Returns the constant value for defined for + * field of register . This value is suitable for direct + * comparison with unshifted values appropriate for use in field + * of register . + */ +#ifndef TH500_PMASYS_SOC_HWPM_H +#define TH500_PMASYS_SOC_HWPM_H + +#define pmasys_cg2_r() (0x13ef1f44U) +#define pmasys_cg2_slcg_f(v) (((v) & 0x1U) << 0U) +#define pmasys_cg2_slcg_m() (0x1U << 0U) +#define pmasys_cg2_slcg_enabled_v() (0x00000000U) +#define pmasys_cg2_slcg_enabled_f() (0x0U) +#define pmasys_cg2_slcg_disabled_v() (0x00000001U) +#define pmasys_cg2_slcg_disabled_f() (0x1U) +#define pmasys_cg2_slcg__prod_v() (0x00000000U) +#define pmasys_cg2_slcg__prod_f() (0x0U) +#define pmasys_channel_control_user_r(i)\ + (0x13ef0a20U + ((i)*384U)) +#define pmasys_channel_control_user_update_bytes_f(v) (((v) & 0x1U) << 16U) +#define pmasys_channel_control_user_update_bytes_m() (0x1U << 16U) +#define pmasys_channel_control_user_update_bytes_doit_v() (0x00000001U) +#define pmasys_channel_control_user_update_bytes_doit_f() (0x10000U) +#define pmasys_channel_mem_blockupper_r(i)\ + (0x13ef0a3cU + ((i)*384U)) +#define pmasys_channel_mem_blockupper_valid_f(v) (((v) & 0x1U) << 31U) +#define pmasys_channel_mem_blockupper_valid_false_v() (0x00000000U) +#define pmasys_channel_mem_blockupper_valid_true_v() (0x00000001U) +#define pmasys_channel_mem_bump_r(i)\ + (0x13ef0a24U + ((i)*384U)) +#define pmasys_channel_mem_block_r(i)\ + (0x13ef0a38U + ((i)*384U)) +#define pmasys_channel_mem_block__size_1_v() (0x00000001U) +#define pmasys_channel_mem_block_base_f(v) (((v) & 0xffffffffU) << 0U) +#define pmasys_channel_mem_block_base_m() (0xffffffffU << 0U) +#define pmasys_channel_mem_block_coalesce_timeout_cycles_f(v)\ + (((v) & 0x7U) << 24U) +#define pmasys_channel_mem_block_coalesce_timeout_cycles_m() (0x7U << 24U) +#define pmasys_channel_mem_block_coalesce_timeout_cycles__prod_v() (0x00000004U) +#define pmasys_channel_mem_block_coalesce_timeout_cycles__prod_f() (0x4000000U) +#define pmasys_channel_outbase_r(i)\ + (0x13ef0a48U + ((i)*384U)) +#define pmasys_channel_outbase_ptr_f(v) (((v) & 0x7ffffffU) << 5U) +#define pmasys_channel_outbase_ptr_m() (0x7ffffffU << 5U) +#define pmasys_channel_outbase_ptr_v(r) (((r) >> 5U) & 0x7ffffffU) +#define pmasys_channel_outbaseupper_r(i)\ + (0x13ef0a4cU + ((i)*384U)) +#define pmasys_channel_outbaseupper_ptr_f(v) (((v) & 0x1ffffffU) << 0U) +#define pmasys_channel_outbaseupper_ptr_m() (0x1ffffffU << 0U) +#define pmasys_channel_outbaseupper_ptr_v(r) (((r) >> 0U) & 0x1ffffffU) +#define pmasys_channel_outsize_r(i)\ + (0x13ef0a50U + ((i)*384U)) +#define pmasys_channel_outsize_numbytes_f(v) (((v) & 0x7ffffffU) << 5U) +#define pmasys_channel_outsize_numbytes_m() (0x7ffffffU << 5U) +#define pmasys_channel_mem_head_r(i)\ + (0x13ef0a54U + ((i)*384U)) +#define pmasys_channel_mem_bytes_addr_r(i)\ + (0x13ef0a5cU + ((i)*384U)) +#define pmasys_channel_mem_bytes_addr_ptr_f(v) (((v) & 0x3fffffffU) << 2U) +#define pmasys_channel_mem_bytes_addr_ptr_m() (0x3fffffffU << 2U) +#define pmasys_channel_config_user_r(i)\ + (0x13ef0a44U + ((i)*384U)) +#define pmasys_channel_config_user_stream_f(v) (((v) & 0x1U) << 0U) +#define pmasys_channel_config_user_stream_m() (0x1U << 0U) +#define pmasys_channel_config_user_stream_disable_f() (0x0U) +#define pmasys_channel_config_user_coalesce_timeout_cycles_f(v)\ + (((v) & 0x7U) << 24U) +#define pmasys_channel_config_user_coalesce_timeout_cycles_m() (0x7U << 24U) +#define pmasys_channel_config_user_coalesce_timeout_cycles__prod_v()\ + (0x00000004U) +#define pmasys_channel_config_user_coalesce_timeout_cycles__prod_f()\ + (0x4000000U) +#define pmasys_channel_status_r(i)\ + (0x13ef0a00U + ((i)*384U)) +#define pmasys_channel_status_engine_status_m() (0x7U << 0U) +#define pmasys_channel_status_engine_status_empty_v() (0x00000000U) +#define pmasys_channel_status_engine_status_empty_f() (0x0U) +#define pmasys_channel_status_engine_status_active_v() (0x00000001U) +#define pmasys_channel_status_engine_status_paused_v() (0x00000002U) +#define pmasys_channel_status_engine_status_quiescent_v() (0x00000003U) +#define pmasys_channel_status_engine_status_stalled_v() (0x00000005U) +#define pmasys_channel_status_engine_status_faulted_v() (0x00000006U) +#define pmasys_channel_status_engine_status_halted_v() (0x00000007U) +#define pmasys_channel_status_membuf_status_f(v) (((v) & 0x1U) << 16U) +#define pmasys_channel_status_membuf_status_m() (0x1U << 16U) +#define pmasys_channel_status_membuf_status_v(r) (((r) >> 16U) & 0x1U) +#define pmasys_channel_status_membuf_status_overflowed_v() (0x00000001U) +#define pmasys_command_slice_trigger_config_user_r(i)\ + (0x13ef0afcU + ((i)*384U)) +#define pmasys_command_slice_trigger_config_user_pma_pulse_f(v)\ + (((v) & 0x1U) << 0U) +#define pmasys_command_slice_trigger_config_user_pma_pulse_m() (0x1U << 0U) +#define pmasys_command_slice_trigger_config_user_pma_pulse_disable_v()\ + (0x00000000U) +#define pmasys_command_slice_trigger_config_user_pma_pulse_disable_f() (0x0U) +#define pmasys_command_slice_trigger_config_user_record_stream_f(v)\ + (((v) & 0x1U) << 8U) +#define pmasys_command_slice_trigger_config_user_record_stream_m() (0x1U << 8U) +#define pmasys_command_slice_trigger_config_user_record_stream_disable_v()\ + (0x00000000U) +#define pmasys_command_slice_trigger_config_user_record_stream_disable_f()\ + (0x0U) +#endif diff --git a/drivers/tegra/hwpm/hal/th500/soc/hw/th500_pmmsys_soc_hwpm.h b/drivers/tegra/hwpm/hal/th500/soc/hw/th500_pmmsys_soc_hwpm.h new file mode 100644 index 0000000..f48f4d0 --- /dev/null +++ b/drivers/tegra/hwpm/hal/th500/soc/hw/th500_pmmsys_soc_hwpm.h @@ -0,0 +1,113 @@ +/* + * Copyright (c) 2022-2023, NVIDIA CORPORATION. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ +/* + * Function/Macro naming determines intended use: + * + * _r(void) : Returns the offset for register . + * + * _o(void) : Returns the offset for element . + * + * _w(void) : Returns the word offset for word (4 byte) element . + * + * __s(void) : Returns size of field of register in bits. + * + * __f(u32 v) : Returns a value based on 'v' which has been shifted + * and masked to place it at field of register . This value + * can be |'d with others to produce a full register value for + * register . + * + * __m(void) : Returns a mask for field of register . This + * value can be ~'d and then &'d to clear the value of field for + * register . + * + * ___f(void) : Returns the constant value after being shifted + * to place it at field of register . This value can be |'d + * with others to produce a full register value for . + * + * __v(u32 r) : Returns the value of field from a full register + * value 'r' after being shifted to place its LSB at bit 0. + * This value is suitable for direct comparison with other unshifted + * values appropriate for use in field of register . + * + * ___v(void) : Returns the constant value for defined for + * field of register . This value is suitable for direct + * comparison with unshifted values appropriate for use in field + * of register . + */ +#ifndef TH500_PMMSYS_SOC_HWPM_H +#define TH500_PMMSYS_SOC_HWPM_H + +#define pmmsys_perdomain_offset_v() (0x00001000U) +#define pmmsys_control_r(i)\ + (0x13e0009cU + ((i)*4096U)) +#define pmmsys_control_mode_f(v) (((v) & 0x7U) << 0U) +#define pmmsys_control_mode_m() (0x7U << 0U) +#define pmmsys_control_mode_disable_v() (0x00000000U) +#define pmmsys_control_mode_disable_f() (0x0U) +#define pmmsys_control_mode_a_v() (0x00000001U) +#define pmmsys_control_mode_b_v() (0x00000002U) +#define pmmsys_control_mode_c_v() (0x00000003U) +#define pmmsys_control_mode_e_v() (0x00000005U) +#define pmmsys_control_mode_null_v() (0x00000007U) +#define pmmsys_sys0_enginestatus_r(i)\ + (0x13e000c8U + ((i)*4096U)) +#define pmmsys_sys0router_enginestatus_r() (0x13ef2050U) +#define pmmsys_sys0router_enginestatus_status_f(v) (((v) & 0x7U) << 0U) +#define pmmsys_sys0router_enginestatus_status_m() (0x7U << 0U) +#define pmmsys_sys0router_enginestatus_status_v(r) (((r) >> 0U) & 0x7U) +#define pmmsys_sys0router_enginestatus_status_empty_v() (0x00000000U) +#define pmmsys_sys0router_enginestatus_status_active_v() (0x00000001U) +#define pmmsys_sys0router_enginestatus_status_paused_v() (0x00000002U) +#define pmmsys_sys0router_enginestatus_status_quiescent_v() (0x00000003U) +#define pmmsys_sys0router_enginestatus_status_stalled_v() (0x00000005U) +#define pmmsys_sys0router_enginestatus_status_faulted_v() (0x00000006U) +#define pmmsys_sys0router_enginestatus_status_halted_v() (0x00000007U) +#define pmmsys_sys0router_cg1_secure_r() (0x13ef2054U) +#define pmmsys_sys0router_cg1_secure_flcg_perfmon_f(v) (((v) & 0x1U) << 31U) +#define pmmsys_sys0router_cg1_secure_flcg_perfmon_m() (0x1U << 31U) +#define pmmsys_sys0router_cg1_secure_flcg_perfmon__prod_v() (0x00000001U) +#define pmmsys_sys0router_cg1_secure_flcg_perfmon__prod_f() (0x80000000U) +#define pmmsys_sys0router_cg1_secure_flcg_perfmon_disabled_v() (0x00000000U) +#define pmmsys_sys0router_cg1_secure_flcg_perfmon_disabled_f() (0x0U) +#define pmmsys_sys0router_cg1_secure_flcg_perfmon_enabled_v() (0x00000001U) +#define pmmsys_sys0router_cg1_secure_flcg_perfmon_enabled_f() (0x80000000U) +#define pmmsys_sys0router_cg2_r() (0x13ef2040U) +#define pmmsys_sys0router_cg2_slcg_m() (0x1U << 31U) +#define pmmsys_sys0router_cg2_slcg_disabled_v() (0x00000001U) +#define pmmsys_sys0router_cg2_slcg_disabled_f() (0x80000000U) +#define pmmsys_sys0router_cg2_slcg_enabled_f() (0x0U) +#define pmmsys_sys0router_perfmon_cg2_secure_r() (0x13ef2058U) +#define pmmsys_sys0router_perfmon_cg2_secure_slcg_f(v) (((v) & 0x1U) << 31U) +#define pmmsys_sys0router_perfmon_cg2_secure_slcg_m() (0x1U << 31U) +#define pmmsys_sys0router_perfmon_cg2_secure_slcg__prod_v() (0x00000000U) +#define pmmsys_sys0router_perfmon_cg2_secure_slcg__prod_f() (0x0U) +#define pmmsys_sys0router_perfmon_cg2_secure_slcg_disabled_v() (0x00000001U) +#define pmmsys_sys0router_perfmon_cg2_secure_slcg_disabled_f() (0x80000000U) +#define pmmsys_sys0router_perfmon_cg2_secure_slcg_enabled_v() (0x00000000U) +#define pmmsys_sys0router_perfmon_cg2_secure_slcg_enabled_f() (0x0U) +#define pmmsys_sys0_enginestatus_r(i)\ + (0x13e000c8U + ((i)*4096U)) +#define pmmsys_sys0_enginestatus_enable_f(v) (((v) & 0x1U) << 8U) +#define pmmsys_sys0_enginestatus_enable_m() (0x1U << 8U) +#define pmmsys_sys0_enginestatus_enable_out_v() (0x00000001U) +#define pmmsys_sys0_enginestatus_enable_out_f() (0x100U) +#define pmmsys_sysrouter_enginestatus_r() (0x13ef2050U) +#define pmmsys_sysrouter_enginestatus_merged_perfmon_status_f(v)\ + (((v) & 0x7U) << 8U) +#define pmmsys_sysrouter_enginestatus_merged_perfmon_status_m() (0x7U << 8U) +#define pmmsys_sysrouter_enginestatus_merged_perfmon_status_v(r)\ + (((r) >> 8U) & 0x7U) +#endif diff --git a/drivers/tegra/hwpm/hal/th500/soc/ip/c2c/th500_c2c.c b/drivers/tegra/hwpm/hal/th500/soc/ip/c2c/th500_c2c.c new file mode 100644 index 0000000..438e6e0 --- /dev/null +++ b/drivers/tegra/hwpm/hal/th500/soc/ip/c2c/th500_c2c.c @@ -0,0 +1,436 @@ +/* + * Copyright (c) 2023, NVIDIA CORPORATION & AFFILIATES. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + */ + +#include "th500_c2c.h" + +#include +#include +#include +#include + +static struct hwpm_ip_aperture th500_c2c_inst0_perfmon_element_static_array[ + TH500_HWPM_IP_C2C_NUM_PERFMON_PER_INST] = { + { + .element_type = HWPM_ELEMENT_PERFMON, + .element_index_mask = BIT(0), + .element_index = 0U, + .dt_mmio = NULL, + .name = "perfmon_c2c0", + .device_index = TH500_CTC0_PERFMON_DEVICE_NODE_INDEX, + .start_abs_pa = addr_map_rpg_pm_ctc0_base_r(), + .end_abs_pa = addr_map_rpg_pm_ctc0_limit_r(), + .start_pa = addr_map_rpg_pm_ctc0_base_r(), + .end_pa = addr_map_rpg_pm_ctc0_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_c2c_inst1_perfmon_element_static_array[ + TH500_HWPM_IP_C2C_NUM_PERFMON_PER_INST] = { + { + .element_type = HWPM_ELEMENT_PERFMON, + .element_index_mask = BIT(0), + .element_index = 0U, + .dt_mmio = NULL, + .name = "perfmon_c2c1", + .device_index = TH500_CTC1_PERFMON_DEVICE_NODE_INDEX, + .start_abs_pa = addr_map_rpg_pm_ctc1_base_r(), + .end_abs_pa = addr_map_rpg_pm_ctc1_limit_r(), + .start_pa = addr_map_rpg_pm_ctc1_base_r(), + .end_pa = addr_map_rpg_pm_ctc1_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_c2c_inst0_perfmux_element_static_array[ + TH500_HWPM_IP_C2C_NUM_PERFMUX_PER_INST] = { + { + .element_type = IP_ELEMENT_PERFMUX, + .element_index_mask = BIT(0), + .element_index = 0U, + .dt_mmio = NULL, + .name = {'\0'}, + .start_abs_pa = addr_map_c2c0_base_r(), + .end_abs_pa = addr_map_c2c0_limit_r(), + .start_pa = addr_map_c2c0_base_r(), + .end_pa = addr_map_c2c0_limit_r(), + .base_pa = 0ULL, + .alist = th500_c2c_alist, + .alist_size = ARRAY_SIZE(th500_c2c_alist), + .fake_registers = NULL, + }, + { + .element_type = IP_ELEMENT_PERFMUX, + .element_index_mask = BIT(1), + .element_index = 1U, + .dt_mmio = NULL, + .name = {'\0'}, + .start_abs_pa = addr_map_c2c1_base_r(), + .end_abs_pa = addr_map_c2c1_limit_r(), + .start_pa = addr_map_c2c1_base_r(), + .end_pa = addr_map_c2c1_limit_r(), + .base_pa = 0ULL, + .alist = th500_c2c_alist, + .alist_size = ARRAY_SIZE(th500_c2c_alist), + .fake_registers = NULL, + }, + { + .element_type = IP_ELEMENT_PERFMUX, + .element_index_mask = BIT(2), + .element_index = 2U, + .dt_mmio = NULL, + .name = {'\0'}, + .start_abs_pa = addr_map_c2c2_base_r(), + .end_abs_pa = addr_map_c2c2_limit_r(), + .start_pa = addr_map_c2c2_base_r(), + .end_pa = addr_map_c2c2_limit_r(), + .base_pa = 0ULL, + .alist = th500_c2c_alist, + .alist_size = ARRAY_SIZE(th500_c2c_alist), + .fake_registers = NULL, + }, + { + .element_type = IP_ELEMENT_PERFMUX, + .element_index_mask = BIT(3), + .element_index = 3U, + .dt_mmio = NULL, + .name = {'\0'}, + .start_abs_pa = addr_map_c2c3_base_r(), + .end_abs_pa = addr_map_c2c3_limit_r(), + .start_pa = addr_map_c2c3_base_r(), + .end_pa = addr_map_c2c3_limit_r(), + .base_pa = 0ULL, + .alist = th500_c2c_alist, + .alist_size = ARRAY_SIZE(th500_c2c_alist), + .fake_registers = NULL, + }, + { + .element_type = IP_ELEMENT_PERFMUX, + .element_index_mask = BIT(4), + .element_index = 4U, + .dt_mmio = NULL, + .name = {'\0'}, + .start_abs_pa = addr_map_c2c4_base_r(), + .end_abs_pa = addr_map_c2c4_limit_r(), + .start_pa = addr_map_c2c4_base_r(), + .end_pa = addr_map_c2c4_limit_r(), + .base_pa = 0ULL, + .alist = th500_c2c_alist, + .alist_size = ARRAY_SIZE(th500_c2c_alist), + .fake_registers = NULL, + }, +}; + +static struct hwpm_ip_aperture th500_c2c_inst1_perfmux_element_static_array[ + TH500_HWPM_IP_C2C_NUM_PERFMUX_PER_INST] = { + { + .element_type = IP_ELEMENT_PERFMUX, + .element_index_mask = BIT(0), + .element_index = 0U, + .dt_mmio = NULL, + .name = {'\0'}, + .start_abs_pa = addr_map_c2c5_base_r(), + .end_abs_pa = addr_map_c2c5_limit_r(), + .start_pa = addr_map_c2c5_base_r(), + .end_pa = addr_map_c2c5_limit_r(), + .base_pa = 0ULL, + .alist = th500_c2c_alist, + .alist_size = ARRAY_SIZE(th500_c2c_alist), + .fake_registers = NULL, + }, + { + .element_type = IP_ELEMENT_PERFMUX, + .element_index_mask = BIT(1), + .element_index = 1U, + .dt_mmio = NULL, + .name = {'\0'}, + .start_abs_pa = addr_map_c2c6_base_r(), + .end_abs_pa = addr_map_c2c6_limit_r(), + .start_pa = addr_map_c2c6_base_r(), + .end_pa = addr_map_c2c6_limit_r(), + .base_pa = 0ULL, + .alist = th500_c2c_alist, + .alist_size = ARRAY_SIZE(th500_c2c_alist), + .fake_registers = NULL, + }, + { + .element_type = IP_ELEMENT_PERFMUX, + .element_index_mask = BIT(2), + .element_index = 2U, + .dt_mmio = NULL, + .name = {'\0'}, + .start_abs_pa = addr_map_c2c7_base_r(), + .end_abs_pa = addr_map_c2c7_limit_r(), + .start_pa = addr_map_c2c7_base_r(), + .end_pa = addr_map_c2c7_limit_r(), + .base_pa = 0ULL, + .alist = th500_c2c_alist, + .alist_size = ARRAY_SIZE(th500_c2c_alist), + .fake_registers = NULL, + }, + { + .element_type = IP_ELEMENT_PERFMUX, + .element_index_mask = BIT(3), + .element_index = 3U, + .dt_mmio = NULL, + .name = {'\0'}, + .start_abs_pa = addr_map_c2c8_base_r(), + .end_abs_pa = addr_map_c2c8_limit_r(), + .start_pa = addr_map_c2c8_base_r(), + .end_pa = addr_map_c2c8_limit_r(), + .base_pa = 0ULL, + .alist = th500_c2c_alist, + .alist_size = ARRAY_SIZE(th500_c2c_alist), + .fake_registers = NULL, + }, + { + .element_type = IP_ELEMENT_PERFMUX, + .element_index_mask = BIT(4), + .element_index = 4U, + .dt_mmio = NULL, + .name = {'\0'}, + .start_abs_pa = addr_map_c2c9_base_r(), + .end_abs_pa = addr_map_c2c9_limit_r(), + .start_pa = addr_map_c2c9_base_r(), + .end_pa = addr_map_c2c9_limit_r(), + .base_pa = 0ULL, + .alist = th500_c2c_alist, + .alist_size = ARRAY_SIZE(th500_c2c_alist), + .fake_registers = NULL, + }, + +}; + +static struct hwpm_ip_aperture th500_c2c_inst0_broadcast_element_static_array[ + TH500_HWPM_IP_C2C_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_c2cs0_base_r(), + .end_abs_pa = addr_map_c2cs0_limit_r(), + .start_pa = 0ULL, + .end_pa = 0ULL, + .base_pa = 0ULL, + .alist = th500_c2c_alist, + .alist_size = ARRAY_SIZE(th500_c2c_alist), + .fake_registers = NULL, + }, +}; + +struct hwpm_ip_aperture th500_c2c_inst1_broadcast_element_static_array[ + TH500_HWPM_IP_C2C_NUM_BROADCAST_PER_INST] = { + { + .element_type = IP_ELEMENT_BROADCAST, + .element_index_mask = BIT(1), + .element_index = 1U, + .dt_mmio = NULL, + .name = {'\0'}, + .start_abs_pa = addr_map_c2cs1_base_r(), + .end_abs_pa = addr_map_c2cs1_limit_r(), + .start_pa = 0ULL, + .end_pa = 0ULL, + .base_pa = 0ULL, + .alist = th500_c2c_alist, + .alist_size = ARRAY_SIZE(th500_c2c_alist), + .fake_registers = NULL, + }, +}; + +/* IP instance array */ +static struct hwpm_ip_inst th500_c2c_inst_static_array[ + TH500_HWPM_IP_C2C_NUM_INSTANCES] = { + { + .hw_inst_mask = BIT(0), + .num_core_elements_per_inst = + TH500_HWPM_IP_C2C_NUM_CORE_ELEMENT_PER_INST, + .element_info = { + /* + * Instance info corresponding to + * TEGRA_HWPM_APERTURE_TYPE_PERFMUX + */ + { + .num_element_per_inst = + TH500_HWPM_IP_C2C_NUM_PERFMUX_PER_INST, + .element_static_array = + th500_c2c_inst0_perfmux_element_static_array, + .range_start = addr_map_c2c0_base_r(), + .range_end = addr_map_c2c4_limit_r(), + .element_stride = addr_map_c2c0_limit_r() - + addr_map_c2c0_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_C2C_NUM_BROADCAST_PER_INST, + .element_static_array = + th500_c2c_inst0_broadcast_element_static_array, + .range_start = addr_map_c2cs0_base_r(), + .range_end = addr_map_c2cs0_limit_r(), + .element_stride = addr_map_c2cs0_limit_r() - + addr_map_c2cs0_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_C2C_NUM_PERFMON_PER_INST, + .element_static_array = + th500_c2c_inst0_perfmon_element_static_array, + .range_start = addr_map_rpg_pm_ctc0_base_r(), + .range_end = addr_map_rpg_pm_ctc0_limit_r(), + .element_stride = addr_map_rpg_pm_ctc0_limit_r() - + addr_map_rpg_pm_ctc0_base_r() + 1ULL, + .element_slots = 0U, + .element_arr = NULL, + }, + }, + .ip_ops = { + .ip_dev = NULL, + .hwpm_ip_pm = NULL, + .hwpm_ip_reg_op = NULL, + }, + + .element_fs_mask = 0U, + }, + { + .hw_inst_mask = BIT(1), + .num_core_elements_per_inst = + TH500_HWPM_IP_C2C_NUM_CORE_ELEMENT_PER_INST, + .element_info = { + /* + * Instance info corresponding to + * TEGRA_HWPM_APERTURE_TYPE_PERFMUX + */ + { + .num_element_per_inst = + TH500_HWPM_IP_C2C_NUM_PERFMUX_PER_INST, + .element_static_array = + th500_c2c_inst1_perfmux_element_static_array, + .range_start = addr_map_c2c5_base_r(), + .range_end = addr_map_c2c9_limit_r(), + .element_stride = addr_map_c2c5_limit_r() - + addr_map_c2c5_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_C2C_NUM_BROADCAST_PER_INST, + .element_static_array = + th500_c2c_inst1_broadcast_element_static_array, + .range_start = addr_map_c2cs1_base_r(), + .range_end = addr_map_c2cs1_limit_r(), + .element_stride = addr_map_c2cs1_limit_r() - + addr_map_c2cs1_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_C2C_NUM_PERFMON_PER_INST, + .element_static_array = + th500_c2c_inst1_perfmon_element_static_array, + .range_start = addr_map_rpg_pm_ctc1_base_r(), + .range_end = addr_map_rpg_pm_ctc1_limit_r(), + .element_stride = addr_map_rpg_pm_ctc1_limit_r() - + addr_map_rpg_pm_ctc1_base_r() + 1ULL, + .element_slots = 0U, + .element_arr = NULL, + }, + }, + .ip_ops = { + .ip_dev = NULL, + .hwpm_ip_pm = NULL, + .hwpm_ip_reg_op = NULL, + }, + + .element_fs_mask = 0U, + }, +}; + +/* IP structure */ +struct hwpm_ip th500_hwpm_ip_c2c = { + .num_instances = TH500_HWPM_IP_C2C_NUM_INSTANCES, + .ip_inst_static_array = th500_c2c_inst_static_array, + + .inst_aperture_info = { + /* + * Instance info corresponding to + * TEGRA_HWPM_APERTURE_TYPE_PERFMUX + */ + { + .range_start = addr_map_c2c0_base_r(), + .range_end = addr_map_c2c9_limit_r(), + .inst_stride = addr_map_c2c4_limit_r() - + addr_map_c2c0_base_r() + 1ULL, + .inst_slots = 0U, + .inst_arr = NULL, + }, + /* + * Instance info corresponding to + * TEGRA_HWPM_APERTURE_TYPE_BROADCAST + */ + { + .range_start = addr_map_c2cs0_base_r(), + .range_end = addr_map_c2cs1_limit_r(), + .inst_stride = addr_map_c2cs0_limit_r() - + addr_map_c2cs0_base_r() + 1ULL, + .inst_slots = 0U, + .inst_arr = NULL, + }, + /* + * Instance info corresponding to + * TEGRA_HWPM_APERTURE_TYPE_PERFMON + */ + { + .range_start = addr_map_rpg_pm_ctc0_base_r(), + .range_end = addr_map_rpg_pm_ctc1_limit_r(), + .inst_stride = addr_map_rpg_pm_ctc0_limit_r() - + addr_map_rpg_pm_ctc0_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/c2c/th500_c2c.h b/drivers/tegra/hwpm/hal/th500/soc/ip/c2c/th500_c2c.h new file mode 100644 index 0000000..5c07fad --- /dev/null +++ b/drivers/tegra/hwpm/hal/th500/soc/ip/c2c/th500_c2c.h @@ -0,0 +1,33 @@ +/* + * Copyright (c) 2023, NVIDIA CORPORATION & AFFILIATES. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + */ +#ifndef TH500_HWPM_IP_C2C_H +#define TH500_HWPM_IP_C2C_H + +#if defined(CONFIG_TH500_HWPM_IP_C2C) +#define TH500_HWPM_ACTIVE_IP_C2C TH500_HWPM_IP_C2C, + +/* This data should ideally be available in HW headers */ +#define TH500_HWPM_IP_C2C_NUM_INSTANCES 2U +#define TH500_HWPM_IP_C2C_NUM_CORE_ELEMENT_PER_INST 1U +#define TH500_HWPM_IP_C2C_NUM_PERFMON_PER_INST 1U +#define TH500_HWPM_IP_C2C_NUM_PERFMUX_PER_INST 5U +#define TH500_HWPM_IP_C2C_NUM_BROADCAST_PER_INST 1U + +extern struct hwpm_ip th500_hwpm_ip_c2c; + +#else +#define TH500_HWPM_ACTIVE_IP_C2C +#endif + +#endif /* TH500_HWPM_IP_C2C_H */ + diff --git a/drivers/tegra/hwpm/hal/th500/soc/ip/mss_channel/th500_mss_channel.c b/drivers/tegra/hwpm/hal/th500/soc/ip/mss_channel/th500_mss_channel.c new file mode 100644 index 0000000..c0835c5 --- /dev/null +++ b/drivers/tegra/hwpm/hal/th500/soc/ip/mss_channel/th500_mss_channel.c @@ -0,0 +1,1159 @@ +/* + * Copyright (c) 2022-2023, NVIDIA CORPORATION & AFFILIATES. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + */ + +#include "th500_mss_channel.h" + +#include +#include +#include +#include + +static struct hwpm_ip_aperture th500_mss_channel_inst0_perfmon_element_static_array[ + TH500_HWPM_IP_MSS_CHANNEL_NUM_PERFMON_PER_INST] = { + { + .element_type = HWPM_ELEMENT_PERFMON, + .element_index_mask = BIT(0), + .element_index = 1U, + .dt_mmio = NULL, + .name = "perfmon_msschannel_parta0", + .device_index = TH500_MSS_CHANNEL_PARTA0_PERFMON_DEVICE_NODE_INDEX, + .start_abs_pa = addr_map_rpg_pm_msschannel0_base_r(), + .end_abs_pa = addr_map_rpg_pm_msschannel0_limit_r(), + .start_pa = addr_map_rpg_pm_msschannel0_base_r(), + .end_pa = addr_map_rpg_pm_msschannel0_limit_r(), + .base_pa = addr_map_rpg_pm_base_r(), + .alist = th500_perfmon_alist, + .alist_size = ARRAY_SIZE(th500_perfmon_alist), + .fake_registers = NULL, + }, + { + .element_type = HWPM_ELEMENT_PERFMON, + .element_index_mask = BIT(1), + .element_index = 2U, + .dt_mmio = NULL, + .name = "perfmon_msschannel_parta1", + .device_index = TH500_MSS_CHANNEL_PARTA1_PERFMON_DEVICE_NODE_INDEX, + .start_abs_pa = addr_map_rpg_pm_msschannel1_base_r(), + .end_abs_pa = addr_map_rpg_pm_msschannel1_limit_r(), + .start_pa = addr_map_rpg_pm_msschannel1_base_r(), + .end_pa = addr_map_rpg_pm_msschannel1_limit_r(), + .base_pa = addr_map_rpg_pm_base_r(), + .alist = th500_perfmon_alist, + .alist_size = ARRAY_SIZE(th500_perfmon_alist), + .fake_registers = NULL, + }, + { + .element_type = HWPM_ELEMENT_PERFMON, + .element_index_mask = BIT(2), + .element_index = 3U, + .dt_mmio = NULL, + .name = "perfmon_msschannel_parta2", + .device_index = TH500_MSS_CHANNEL_PARTA2_PERFMON_DEVICE_NODE_INDEX, + .start_abs_pa = addr_map_rpg_pm_msschannel2_base_r(), + .end_abs_pa = addr_map_rpg_pm_msschannel2_limit_r(), + .start_pa = addr_map_rpg_pm_msschannel2_base_r(), + .end_pa = addr_map_rpg_pm_msschannel2_limit_r(), + .base_pa = addr_map_rpg_pm_base_r(), + .alist = th500_perfmon_alist, + .alist_size = ARRAY_SIZE(th500_perfmon_alist), + .fake_registers = NULL, + }, + { + .element_type = HWPM_ELEMENT_PERFMON, + .element_index_mask = BIT(3), + .element_index = 4U, + .dt_mmio = NULL, + .name = "perfmon_msschannel_parta3", + .device_index = TH500_MSS_CHANNEL_PARTA3_PERFMON_DEVICE_NODE_INDEX, + .start_abs_pa = addr_map_rpg_pm_msschannel3_base_r(), + .end_abs_pa = addr_map_rpg_pm_msschannel3_limit_r(), + .start_pa = addr_map_rpg_pm_msschannel3_base_r(), + .end_pa = addr_map_rpg_pm_msschannel3_limit_r(), + .base_pa = addr_map_rpg_pm_base_r(), + .alist = th500_perfmon_alist, + .alist_size = ARRAY_SIZE(th500_perfmon_alist), + .fake_registers = NULL, + }, + { + .element_type = HWPM_ELEMENT_PERFMON, + .element_index_mask = BIT(4), + .element_index = 5U, + .dt_mmio = NULL, + .name = "perfmon_msschannel_partb0", + .device_index = TH500_MSS_CHANNEL_PARTB0_PERFMON_DEVICE_NODE_INDEX, + .start_abs_pa = addr_map_rpg_pm_msschannel4_base_r(), + .end_abs_pa = addr_map_rpg_pm_msschannel4_limit_r(), + .start_pa = addr_map_rpg_pm_msschannel4_base_r(), + .end_pa = addr_map_rpg_pm_msschannel4_limit_r(), + .base_pa = addr_map_rpg_pm_base_r(), + .alist = th500_perfmon_alist, + .alist_size = ARRAY_SIZE(th500_perfmon_alist), + .fake_registers = NULL, + }, + { + .element_type = HWPM_ELEMENT_PERFMON, + .element_index_mask = BIT(5), + .element_index = 6U, + .dt_mmio = NULL, + .name = "perfmon_msschannel_partb1", + .device_index = TH500_MSS_CHANNEL_PARTB1_PERFMON_DEVICE_NODE_INDEX, + .start_abs_pa = addr_map_rpg_pm_msschannel5_base_r(), + .end_abs_pa = addr_map_rpg_pm_msschannel5_limit_r(), + .start_pa = addr_map_rpg_pm_msschannel5_base_r(), + .end_pa = addr_map_rpg_pm_msschannel5_limit_r(), + .base_pa = addr_map_rpg_pm_base_r(), + .alist = th500_perfmon_alist, + .alist_size = ARRAY_SIZE(th500_perfmon_alist), + .fake_registers = NULL, + }, + { + .element_type = HWPM_ELEMENT_PERFMON, + .element_index_mask = BIT(6), + .element_index = 7U, + .dt_mmio = NULL, + .name = "perfmon_msschannel_partb2", + .device_index = TH500_MSS_CHANNEL_PARTB2_PERFMON_DEVICE_NODE_INDEX, + .start_abs_pa = addr_map_rpg_pm_msschannel6_base_r(), + .end_abs_pa = addr_map_rpg_pm_msschannel6_limit_r(), + .start_pa = addr_map_rpg_pm_msschannel6_base_r(), + .end_pa = addr_map_rpg_pm_msschannel6_limit_r(), + .base_pa = addr_map_rpg_pm_base_r(), + .alist = th500_perfmon_alist, + .alist_size = ARRAY_SIZE(th500_perfmon_alist), + .fake_registers = NULL, + }, + { + .element_type = HWPM_ELEMENT_PERFMON, + .element_index_mask = BIT(7), + .element_index = 8U, + .dt_mmio = NULL, + .name = "perfmon_msschannel_partb3", + .device_index = TH500_MSS_CHANNEL_PARTB3_PERFMON_DEVICE_NODE_INDEX, + .start_abs_pa = addr_map_rpg_pm_msschannel7_base_r(), + .end_abs_pa = addr_map_rpg_pm_msschannel7_limit_r(), + .start_pa = addr_map_rpg_pm_msschannel7_base_r(), + .end_pa = addr_map_rpg_pm_msschannel7_limit_r(), + .base_pa = addr_map_rpg_pm_base_r(), + .alist = th500_perfmon_alist, + .alist_size = ARRAY_SIZE(th500_perfmon_alist), + .fake_registers = NULL, + }, + { + .element_type = HWPM_ELEMENT_PERFMON, + .element_index_mask = BIT(8), + .element_index = 9U, + .dt_mmio = NULL, + .name = "perfmon_msschannel_partc0", + .device_index = TH500_MSS_CHANNEL_PARTC0_PERFMON_DEVICE_NODE_INDEX, + .start_abs_pa = addr_map_rpg_pm_msschannel8_base_r(), + .end_abs_pa = addr_map_rpg_pm_msschannel8_limit_r(), + .start_pa = addr_map_rpg_pm_msschannel8_base_r(), + .end_pa = addr_map_rpg_pm_msschannel8_limit_r(), + .base_pa = addr_map_rpg_pm_base_r(), + .alist = th500_perfmon_alist, + .alist_size = ARRAY_SIZE(th500_perfmon_alist), + .fake_registers = NULL, + }, + { + .element_type = HWPM_ELEMENT_PERFMON, + .element_index_mask = BIT(9), + .element_index = 10U, + .dt_mmio = NULL, + .name = "perfmon_msschannel_partc1", + .device_index = TH500_MSS_CHANNEL_PARTC1_PERFMON_DEVICE_NODE_INDEX, + .start_abs_pa = addr_map_rpg_pm_msschannel9_base_r(), + .end_abs_pa = addr_map_rpg_pm_msschannel9_limit_r(), + .start_pa = addr_map_rpg_pm_msschannel9_base_r(), + .end_pa = addr_map_rpg_pm_msschannel9_limit_r(), + .base_pa = addr_map_rpg_pm_base_r(), + .alist = th500_perfmon_alist, + .alist_size = ARRAY_SIZE(th500_perfmon_alist), + .fake_registers = NULL, + }, + { + .element_type = HWPM_ELEMENT_PERFMON, + .element_index_mask = BIT(10), + .element_index = 11U, + .dt_mmio = NULL, + .name = "perfmon_msschannel_partc2", + .device_index = TH500_MSS_CHANNEL_PARTC2_PERFMON_DEVICE_NODE_INDEX, + .start_abs_pa = addr_map_rpg_pm_msschannel10_base_r(), + .end_abs_pa = addr_map_rpg_pm_msschannel10_limit_r(), + .start_pa = addr_map_rpg_pm_msschannel10_base_r(), + .end_pa = addr_map_rpg_pm_msschannel10_limit_r(), + .base_pa = addr_map_rpg_pm_base_r(), + .alist = th500_perfmon_alist, + .alist_size = ARRAY_SIZE(th500_perfmon_alist), + .fake_registers = NULL, + }, + { + .element_type = HWPM_ELEMENT_PERFMON, + .element_index_mask = BIT(11), + .element_index = 12U, + .dt_mmio = NULL, + .name = "perfmon_msschannel_partc3", + .device_index = TH500_MSS_CHANNEL_PARTC3_PERFMON_DEVICE_NODE_INDEX, + .start_abs_pa = addr_map_rpg_pm_msschannel11_base_r(), + .end_abs_pa = addr_map_rpg_pm_msschannel11_limit_r(), + .start_pa = addr_map_rpg_pm_msschannel11_base_r(), + .end_pa = addr_map_rpg_pm_msschannel11_limit_r(), + .base_pa = addr_map_rpg_pm_base_r(), + .alist = th500_perfmon_alist, + .alist_size = ARRAY_SIZE(th500_perfmon_alist), + .fake_registers = NULL, + }, + { + .element_type = HWPM_ELEMENT_PERFMON, + .element_index_mask = BIT(12), + .element_index = 13U, + .dt_mmio = NULL, + .name = "perfmon_msschannel_partd0", + .device_index = TH500_MSS_CHANNEL_PARTD0_PERFMON_DEVICE_NODE_INDEX, + .start_abs_pa = addr_map_rpg_pm_msschannel12_base_r(), + .end_abs_pa = addr_map_rpg_pm_msschannel12_limit_r(), + .start_pa = addr_map_rpg_pm_msschannel12_base_r(), + .end_pa = addr_map_rpg_pm_msschannel12_limit_r(), + .base_pa = addr_map_rpg_pm_base_r(), + .alist = th500_perfmon_alist, + .alist_size = ARRAY_SIZE(th500_perfmon_alist), + .fake_registers = NULL, + }, + { + .element_type = HWPM_ELEMENT_PERFMON, + .element_index_mask = BIT(13), + .element_index = 14U, + .dt_mmio = NULL, + .name = "perfmon_msschannel_partd1", + .device_index = TH500_MSS_CHANNEL_PARTD1_PERFMON_DEVICE_NODE_INDEX, + .start_abs_pa = addr_map_rpg_pm_msschannel13_base_r(), + .end_abs_pa = addr_map_rpg_pm_msschannel13_limit_r(), + .start_pa = addr_map_rpg_pm_msschannel13_base_r(), + .end_pa = addr_map_rpg_pm_msschannel13_limit_r(), + .base_pa = addr_map_rpg_pm_base_r(), + .alist = th500_perfmon_alist, + .alist_size = ARRAY_SIZE(th500_perfmon_alist), + .fake_registers = NULL, + }, + { + .element_type = HWPM_ELEMENT_PERFMON, + .element_index_mask = BIT(14), + .element_index = 15U, + .dt_mmio = NULL, + .name = "perfmon_msschannel_partd2", + .device_index = TH500_MSS_CHANNEL_PARTD2_PERFMON_DEVICE_NODE_INDEX, + .start_abs_pa = addr_map_rpg_pm_msschannel14_base_r(), + .end_abs_pa = addr_map_rpg_pm_msschannel14_limit_r(), + .start_pa = addr_map_rpg_pm_msschannel14_base_r(), + .end_pa = addr_map_rpg_pm_msschannel14_limit_r(), + .base_pa = addr_map_rpg_pm_base_r(), + .alist = th500_perfmon_alist, + .alist_size = ARRAY_SIZE(th500_perfmon_alist), + .fake_registers = NULL, + }, + { + .element_type = HWPM_ELEMENT_PERFMON, + .element_index_mask = BIT(15), + .element_index = 16U, + .dt_mmio = NULL, + .name = "perfmon_msschannel_partd3", + .device_index = TH500_MSS_CHANNEL_PARTD3_PERFMON_DEVICE_NODE_INDEX, + .start_abs_pa = addr_map_rpg_pm_msschannel15_base_r(), + .end_abs_pa = addr_map_rpg_pm_msschannel15_limit_r(), + .start_pa = addr_map_rpg_pm_msschannel15_base_r(), + .end_pa = addr_map_rpg_pm_msschannel15_limit_r(), + .base_pa = addr_map_rpg_pm_base_r(), + .alist = th500_perfmon_alist, + .alist_size = ARRAY_SIZE(th500_perfmon_alist), + .fake_registers = NULL, + }, + { + .element_type = HWPM_ELEMENT_PERFMON, + .element_index_mask = BIT(16), + .element_index = 17U, + .dt_mmio = NULL, + .name = "perfmon_msschannel_parte0", + .device_index = TH500_MSS_CHANNEL_PARTE0_PERFMON_DEVICE_NODE_INDEX, + .start_abs_pa = addr_map_rpg_pm_msschannel16_base_r(), + .end_abs_pa = addr_map_rpg_pm_msschannel16_limit_r(), + .start_pa = addr_map_rpg_pm_msschannel16_base_r(), + .end_pa = addr_map_rpg_pm_msschannel16_limit_r(), + .base_pa = addr_map_rpg_pm_base_r(), + .alist = th500_perfmon_alist, + .alist_size = ARRAY_SIZE(th500_perfmon_alist), + .fake_registers = NULL, + }, + { + .element_type = HWPM_ELEMENT_PERFMON, + .element_index_mask = BIT(17), + .element_index = 18U, + .dt_mmio = NULL, + .name = "perfmon_msschannel_parte1", + .device_index = TH500_MSS_CHANNEL_PARTE1_PERFMON_DEVICE_NODE_INDEX, + .start_abs_pa = addr_map_rpg_pm_msschannel17_base_r(), + .end_abs_pa = addr_map_rpg_pm_msschannel17_limit_r(), + .start_pa = addr_map_rpg_pm_msschannel17_base_r(), + .end_pa = addr_map_rpg_pm_msschannel17_limit_r(), + .base_pa = addr_map_rpg_pm_base_r(), + .alist = th500_perfmon_alist, + .alist_size = ARRAY_SIZE(th500_perfmon_alist), + .fake_registers = NULL, + }, + { + .element_type = HWPM_ELEMENT_PERFMON, + .element_index_mask = BIT(18), + .element_index = 19U, + .dt_mmio = NULL, + .name = "perfmon_msschannel_parte2", + .device_index = TH500_MSS_CHANNEL_PARTE2_PERFMON_DEVICE_NODE_INDEX, + .start_abs_pa = addr_map_rpg_pm_msschannel18_base_r(), + .end_abs_pa = addr_map_rpg_pm_msschannel18_limit_r(), + .start_pa = addr_map_rpg_pm_msschannel18_base_r(), + .end_pa = addr_map_rpg_pm_msschannel18_limit_r(), + .base_pa = addr_map_rpg_pm_base_r(), + .alist = th500_perfmon_alist, + .alist_size = ARRAY_SIZE(th500_perfmon_alist), + .fake_registers = NULL, + }, + { + .element_type = HWPM_ELEMENT_PERFMON, + .element_index_mask = BIT(19), + .element_index = 20U, + .dt_mmio = NULL, + .name = "perfmon_msschannel_parte3", + .device_index = TH500_MSS_CHANNEL_PARTE3_PERFMON_DEVICE_NODE_INDEX, + .start_abs_pa = addr_map_rpg_pm_msschannel19_base_r(), + .end_abs_pa = addr_map_rpg_pm_msschannel19_limit_r(), + .start_pa = addr_map_rpg_pm_msschannel19_base_r(), + .end_pa = addr_map_rpg_pm_msschannel19_limit_r(), + .base_pa = addr_map_rpg_pm_base_r(), + .alist = th500_perfmon_alist, + .alist_size = ARRAY_SIZE(th500_perfmon_alist), + .fake_registers = NULL, + }, + { + .element_type = HWPM_ELEMENT_PERFMON, + .element_index_mask = BIT(20), + .element_index = 21U, + .dt_mmio = NULL, + .name = "perfmon_msschannel_partf0", + .device_index = TH500_MSS_CHANNEL_PARTF0_PERFMON_DEVICE_NODE_INDEX, + .start_abs_pa = addr_map_rpg_pm_msschannel20_base_r(), + .end_abs_pa = addr_map_rpg_pm_msschannel20_limit_r(), + .start_pa = addr_map_rpg_pm_msschannel20_base_r(), + .end_pa = addr_map_rpg_pm_msschannel20_limit_r(), + .base_pa = addr_map_rpg_pm_base_r(), + .alist = th500_perfmon_alist, + .alist_size = ARRAY_SIZE(th500_perfmon_alist), + .fake_registers = NULL, + }, + { + .element_type = HWPM_ELEMENT_PERFMON, + .element_index_mask = BIT(21), + .element_index = 22U, + .dt_mmio = NULL, + .name = "perfmon_msschannel_partf1", + .device_index = TH500_MSS_CHANNEL_PARTF1_PERFMON_DEVICE_NODE_INDEX, + .start_abs_pa = addr_map_rpg_pm_msschannel21_base_r(), + .end_abs_pa = addr_map_rpg_pm_msschannel21_limit_r(), + .start_pa = addr_map_rpg_pm_msschannel21_base_r(), + .end_pa = addr_map_rpg_pm_msschannel21_limit_r(), + .base_pa = addr_map_rpg_pm_base_r(), + .alist = th500_perfmon_alist, + .alist_size = ARRAY_SIZE(th500_perfmon_alist), + .fake_registers = NULL, + }, + { + .element_type = HWPM_ELEMENT_PERFMON, + .element_index_mask = BIT(22), + .element_index = 23U, + .dt_mmio = NULL, + .name = "perfmon_msschannel_partf2", + .device_index = TH500_MSS_CHANNEL_PARTF2_PERFMON_DEVICE_NODE_INDEX, + .start_abs_pa = addr_map_rpg_pm_msschannel22_base_r(), + .end_abs_pa = addr_map_rpg_pm_msschannel22_limit_r(), + .start_pa = addr_map_rpg_pm_msschannel22_base_r(), + .end_pa = addr_map_rpg_pm_msschannel22_limit_r(), + .base_pa = addr_map_rpg_pm_base_r(), + .alist = th500_perfmon_alist, + .alist_size = ARRAY_SIZE(th500_perfmon_alist), + .fake_registers = NULL, + }, + { + .element_type = HWPM_ELEMENT_PERFMON, + .element_index_mask = BIT(23), + .element_index = 24U, + .dt_mmio = NULL, + .name = "perfmon_msschannel_partf3", + .device_index = TH500_MSS_CHANNEL_PARTF3_PERFMON_DEVICE_NODE_INDEX, + .start_abs_pa = addr_map_rpg_pm_msschannel23_base_r(), + .end_abs_pa = addr_map_rpg_pm_msschannel23_limit_r(), + .start_pa = addr_map_rpg_pm_msschannel23_base_r(), + .end_pa = addr_map_rpg_pm_msschannel23_limit_r(), + .base_pa = addr_map_rpg_pm_base_r(), + .alist = th500_perfmon_alist, + .alist_size = ARRAY_SIZE(th500_perfmon_alist), + .fake_registers = NULL, + }, + { + .element_type = HWPM_ELEMENT_PERFMON, + .element_index_mask = BIT(24), + .element_index = 25U, + .dt_mmio = NULL, + .name = "perfmon_msschannel_partg0", + .device_index = TH500_MSS_CHANNEL_PARTG0_PERFMON_DEVICE_NODE_INDEX, + .start_abs_pa = addr_map_rpg_pm_msschannel24_base_r(), + .end_abs_pa = addr_map_rpg_pm_msschannel24_limit_r(), + .start_pa = addr_map_rpg_pm_msschannel24_base_r(), + .end_pa = addr_map_rpg_pm_msschannel24_limit_r(), + .base_pa = addr_map_rpg_pm_base_r(), + .alist = th500_perfmon_alist, + .alist_size = ARRAY_SIZE(th500_perfmon_alist), + .fake_registers = NULL, + }, + { + .element_type = HWPM_ELEMENT_PERFMON, + .element_index_mask = BIT(25), + .element_index = 26U, + .dt_mmio = NULL, + .name = "perfmon_msschannel_partg1", + .device_index = TH500_MSS_CHANNEL_PARTG1_PERFMON_DEVICE_NODE_INDEX, + .start_abs_pa = addr_map_rpg_pm_msschannel25_base_r(), + .end_abs_pa = addr_map_rpg_pm_msschannel25_limit_r(), + .start_pa = addr_map_rpg_pm_msschannel25_base_r(), + .end_pa = addr_map_rpg_pm_msschannel25_limit_r(), + .base_pa = addr_map_rpg_pm_base_r(), + .alist = th500_perfmon_alist, + .alist_size = ARRAY_SIZE(th500_perfmon_alist), + .fake_registers = NULL, + }, + { + .element_type = HWPM_ELEMENT_PERFMON, + .element_index_mask = BIT(26), + .element_index = 27U, + .dt_mmio = NULL, + .name = "perfmon_msschannel_partg2", + .device_index = TH500_MSS_CHANNEL_PARTG2_PERFMON_DEVICE_NODE_INDEX, + .start_abs_pa = addr_map_rpg_pm_msschannel26_base_r(), + .end_abs_pa = addr_map_rpg_pm_msschannel26_limit_r(), + .start_pa = addr_map_rpg_pm_msschannel26_base_r(), + .end_pa = addr_map_rpg_pm_msschannel26_limit_r(), + .base_pa = addr_map_rpg_pm_base_r(), + .alist = th500_perfmon_alist, + .alist_size = ARRAY_SIZE(th500_perfmon_alist), + .fake_registers = NULL, + }, + { + .element_type = HWPM_ELEMENT_PERFMON, + .element_index_mask = BIT(27), + .element_index = 28U, + .dt_mmio = NULL, + .name = "perfmon_msschannel_partg3", + .device_index = TH500_MSS_CHANNEL_PARTG3_PERFMON_DEVICE_NODE_INDEX, + .start_abs_pa = addr_map_rpg_pm_msschannel27_base_r(), + .end_abs_pa = addr_map_rpg_pm_msschannel27_limit_r(), + .start_pa = addr_map_rpg_pm_msschannel27_base_r(), + .end_pa = addr_map_rpg_pm_msschannel27_limit_r(), + .base_pa = addr_map_rpg_pm_base_r(), + .alist = th500_perfmon_alist, + .alist_size = ARRAY_SIZE(th500_perfmon_alist), + .fake_registers = NULL, + }, + { + .element_type = HWPM_ELEMENT_PERFMON, + .element_index_mask = BIT(28), + .element_index = 29U, + .dt_mmio = NULL, + .name = "perfmon_msschannel_parth0", + .device_index = TH500_MSS_CHANNEL_PARTH0_PERFMON_DEVICE_NODE_INDEX, + .start_abs_pa = addr_map_rpg_pm_msschannel28_base_r(), + .end_abs_pa = addr_map_rpg_pm_msschannel28_limit_r(), + .start_pa = addr_map_rpg_pm_msschannel28_base_r(), + .end_pa = addr_map_rpg_pm_msschannel28_limit_r(), + .base_pa = addr_map_rpg_pm_base_r(), + .alist = th500_perfmon_alist, + .alist_size = ARRAY_SIZE(th500_perfmon_alist), + .fake_registers = NULL, + }, + { + .element_type = HWPM_ELEMENT_PERFMON, + .element_index_mask = BIT(29), + .element_index = 30U, + .dt_mmio = NULL, + .name = "perfmon_msschannel_parth1", + .device_index = TH500_MSS_CHANNEL_PARTH1_PERFMON_DEVICE_NODE_INDEX, + .start_abs_pa = addr_map_rpg_pm_msschannel29_base_r(), + .end_abs_pa = addr_map_rpg_pm_msschannel29_limit_r(), + .start_pa = addr_map_rpg_pm_msschannel29_base_r(), + .end_pa = addr_map_rpg_pm_msschannel29_limit_r(), + .base_pa = addr_map_rpg_pm_base_r(), + .alist = th500_perfmon_alist, + .alist_size = ARRAY_SIZE(th500_perfmon_alist), + .fake_registers = NULL, + }, + { + .element_type = HWPM_ELEMENT_PERFMON, + .element_index_mask = BIT(30), + .element_index = 31U, + .dt_mmio = NULL, + .name = "perfmon_msschannel_parth2", + .device_index = TH500_MSS_CHANNEL_PARTH2_PERFMON_DEVICE_NODE_INDEX, + .start_abs_pa = addr_map_rpg_pm_msschannel30_base_r(), + .end_abs_pa = addr_map_rpg_pm_msschannel30_limit_r(), + .start_pa = addr_map_rpg_pm_msschannel30_base_r(), + .end_pa = addr_map_rpg_pm_msschannel30_limit_r(), + .base_pa = addr_map_rpg_pm_base_r(), + .alist = th500_perfmon_alist, + .alist_size = ARRAY_SIZE(th500_perfmon_alist), + .fake_registers = NULL, + }, + { + .element_type = HWPM_ELEMENT_PERFMON, + .element_index_mask = BIT(31), + .element_index = 32U, + .dt_mmio = NULL, + .name = "perfmon_msschannel_parth3", + .device_index = TH500_MSS_CHANNEL_PARTH3_PERFMON_DEVICE_NODE_INDEX, + .start_abs_pa = addr_map_rpg_pm_msschannel31_base_r(), + .end_abs_pa = addr_map_rpg_pm_msschannel31_limit_r(), + .start_pa = addr_map_rpg_pm_msschannel31_base_r(), + .end_pa = addr_map_rpg_pm_msschannel31_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_mss_channel_inst0_perfmux_element_static_array[ + TH500_HWPM_IP_MSS_CHANNEL_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_mss_channel_alist, + .alist_size = ARRAY_SIZE(th500_mss_channel_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_mss_channel_alist, + .alist_size = ARRAY_SIZE(th500_mss_channel_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_mss_channel_alist, + .alist_size = ARRAY_SIZE(th500_mss_channel_alist), + .fake_registers = NULL, + }, + { + .element_type = IP_ELEMENT_PERFMUX, + .element_index_mask = BIT(3), + .element_index = 4U, + .dt_mmio = NULL, + .name = {'\0'}, + .start_abs_pa = addr_map_mc3_base_r(), + .end_abs_pa = addr_map_mc3_limit_r(), + .start_pa = addr_map_mc3_base_r(), + .end_pa = addr_map_mc3_limit_r(), + .base_pa = 0ULL, + .alist = th500_mss_channel_alist, + .alist_size = ARRAY_SIZE(th500_mss_channel_alist), + .fake_registers = NULL, + }, + { + .element_type = IP_ELEMENT_PERFMUX, + .element_index_mask = BIT(4), + .element_index = 5U, + .dt_mmio = NULL, + .name = {'\0'}, + .start_abs_pa = addr_map_mc4_base_r(), + .end_abs_pa = addr_map_mc4_limit_r(), + .start_pa = addr_map_mc4_base_r(), + .end_pa = addr_map_mc4_limit_r(), + .base_pa = 0ULL, + .alist = th500_mss_channel_alist, + .alist_size = ARRAY_SIZE(th500_mss_channel_alist), + .fake_registers = NULL, + }, + { + .element_type = IP_ELEMENT_PERFMUX, + .element_index_mask = BIT(5), + .element_index = 6U, + .dt_mmio = NULL, + .name = {'\0'}, + .start_abs_pa = addr_map_mc5_base_r(), + .end_abs_pa = addr_map_mc5_limit_r(), + .start_pa = addr_map_mc5_base_r(), + .end_pa = addr_map_mc5_limit_r(), + .base_pa = 0ULL, + .alist = th500_mss_channel_alist, + .alist_size = ARRAY_SIZE(th500_mss_channel_alist), + .fake_registers = NULL, + }, + { + .element_type = IP_ELEMENT_PERFMUX, + .element_index_mask = BIT(6), + .element_index = 7U, + .dt_mmio = NULL, + .name = {'\0'}, + .start_abs_pa = addr_map_mc6_base_r(), + .end_abs_pa = addr_map_mc6_limit_r(), + .start_pa = addr_map_mc6_base_r(), + .end_pa = addr_map_mc6_limit_r(), + .base_pa = 0ULL, + .alist = th500_mss_channel_alist, + .alist_size = ARRAY_SIZE(th500_mss_channel_alist), + .fake_registers = NULL, + }, + { + .element_type = IP_ELEMENT_PERFMUX, + .element_index_mask = BIT(7), + .element_index = 8U, + .dt_mmio = NULL, + .name = {'\0'}, + .start_abs_pa = addr_map_mc7_base_r(), + .end_abs_pa = addr_map_mc7_limit_r(), + .start_pa = addr_map_mc7_base_r(), + .end_pa = addr_map_mc7_limit_r(), + .base_pa = 0ULL, + .alist = th500_mss_channel_alist, + .alist_size = ARRAY_SIZE(th500_mss_channel_alist), + .fake_registers = NULL, + }, + { + .element_type = IP_ELEMENT_PERFMUX, + .element_index_mask = BIT(8), + .element_index = 9U, + .dt_mmio = NULL, + .name = {'\0'}, + .start_abs_pa = addr_map_mc8_base_r(), + .end_abs_pa = addr_map_mc8_limit_r(), + .start_pa = addr_map_mc8_base_r(), + .end_pa = addr_map_mc8_limit_r(), + .base_pa = 0ULL, + .alist = th500_mss_channel_alist, + .alist_size = ARRAY_SIZE(th500_mss_channel_alist), + .fake_registers = NULL, + }, + { + .element_type = IP_ELEMENT_PERFMUX, + .element_index_mask = BIT(9), + .element_index = 10U, + .dt_mmio = NULL, + .name = {'\0'}, + .start_abs_pa = addr_map_mc9_base_r(), + .end_abs_pa = addr_map_mc9_limit_r(), + .start_pa = addr_map_mc9_base_r(), + .end_pa = addr_map_mc9_limit_r(), + .base_pa = 0ULL, + .alist = th500_mss_channel_alist, + .alist_size = ARRAY_SIZE(th500_mss_channel_alist), + .fake_registers = NULL, + }, + { + .element_type = IP_ELEMENT_PERFMUX, + .element_index_mask = BIT(10), + .element_index = 11U, + .dt_mmio = NULL, + .name = {'\0'}, + .start_abs_pa = addr_map_mc10_base_r(), + .end_abs_pa = addr_map_mc10_limit_r(), + .start_pa = addr_map_mc10_base_r(), + .end_pa = addr_map_mc10_limit_r(), + .base_pa = 0ULL, + .alist = th500_mss_channel_alist, + .alist_size = ARRAY_SIZE(th500_mss_channel_alist), + .fake_registers = NULL, + }, + { + .element_type = IP_ELEMENT_PERFMUX, + .element_index_mask = BIT(11), + .element_index = 12U, + .dt_mmio = NULL, + .name = {'\0'}, + .start_abs_pa = addr_map_mc11_base_r(), + .end_abs_pa = addr_map_mc11_limit_r(), + .start_pa = addr_map_mc11_base_r(), + .end_pa = addr_map_mc11_limit_r(), + .base_pa = 0ULL, + .alist = th500_mss_channel_alist, + .alist_size = ARRAY_SIZE(th500_mss_channel_alist), + .fake_registers = NULL, + }, + { + .element_type = IP_ELEMENT_PERFMUX, + .element_index_mask = BIT(12), + .element_index = 13U, + .dt_mmio = NULL, + .name = {'\0'}, + .start_abs_pa = addr_map_mc12_base_r(), + .end_abs_pa = addr_map_mc12_limit_r(), + .start_pa = addr_map_mc12_base_r(), + .end_pa = addr_map_mc12_limit_r(), + .base_pa = 0ULL, + .alist = th500_mss_channel_alist, + .alist_size = ARRAY_SIZE(th500_mss_channel_alist), + .fake_registers = NULL, + }, + { + .element_type = IP_ELEMENT_PERFMUX, + .element_index_mask = BIT(13), + .element_index = 14U, + .dt_mmio = NULL, + .name = {'\0'}, + .start_abs_pa = addr_map_mc13_base_r(), + .end_abs_pa = addr_map_mc13_limit_r(), + .start_pa = addr_map_mc13_base_r(), + .end_pa = addr_map_mc13_limit_r(), + .base_pa = 0ULL, + .alist = th500_mss_channel_alist, + .alist_size = ARRAY_SIZE(th500_mss_channel_alist), + .fake_registers = NULL, + }, + { + .element_type = IP_ELEMENT_PERFMUX, + .element_index_mask = BIT(14), + .element_index = 15U, + .dt_mmio = NULL, + .name = {'\0'}, + .start_abs_pa = addr_map_mc14_base_r(), + .end_abs_pa = addr_map_mc14_limit_r(), + .start_pa = addr_map_mc14_base_r(), + .end_pa = addr_map_mc14_limit_r(), + .base_pa = 0ULL, + .alist = th500_mss_channel_alist, + .alist_size = ARRAY_SIZE(th500_mss_channel_alist), + .fake_registers = NULL, + }, + { + .element_type = IP_ELEMENT_PERFMUX, + .element_index_mask = BIT(15), + .element_index = 16U, + .dt_mmio = NULL, + .name = {'\0'}, + .start_abs_pa = addr_map_mc15_base_r(), + .end_abs_pa = addr_map_mc15_limit_r(), + .start_pa = addr_map_mc15_base_r(), + .end_pa = addr_map_mc15_limit_r(), + .base_pa = 0ULL, + .alist = th500_mss_channel_alist, + .alist_size = ARRAY_SIZE(th500_mss_channel_alist), + .fake_registers = NULL, + }, + { + .element_type = IP_ELEMENT_PERFMUX, + .element_index_mask = BIT(16), + .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_mss_channel_alist, + .alist_size = ARRAY_SIZE(th500_mss_channel_alist), + .fake_registers = NULL, + }, + { + .element_type = IP_ELEMENT_PERFMUX, + .element_index_mask = BIT(17), + .element_index = 18U, + .dt_mmio = NULL, + .name = {'\0'}, + .start_abs_pa = addr_map_mc17_base_r(), + .end_abs_pa = addr_map_mc17_limit_r(), + .start_pa = addr_map_mc17_base_r(), + .end_pa = addr_map_mc17_limit_r(), + .base_pa = 0ULL, + .alist = th500_mss_channel_alist, + .alist_size = ARRAY_SIZE(th500_mss_channel_alist), + .fake_registers = NULL, + }, + { + .element_type = IP_ELEMENT_PERFMUX, + .element_index_mask = BIT(18), + .element_index = 19U, + .dt_mmio = NULL, + .name = {'\0'}, + .start_abs_pa = addr_map_mc18_base_r(), + .end_abs_pa = addr_map_mc18_limit_r(), + .start_pa = addr_map_mc18_base_r(), + .end_pa = addr_map_mc18_limit_r(), + .base_pa = 0ULL, + .alist = th500_mss_channel_alist, + .alist_size = ARRAY_SIZE(th500_mss_channel_alist), + .fake_registers = NULL, + }, + { + .element_type = IP_ELEMENT_PERFMUX, + .element_index_mask = BIT(19), + .element_index = 20U, + .dt_mmio = NULL, + .name = {'\0'}, + .start_abs_pa = addr_map_mc19_base_r(), + .end_abs_pa = addr_map_mc19_limit_r(), + .start_pa = addr_map_mc19_base_r(), + .end_pa = addr_map_mc19_limit_r(), + .base_pa = 0ULL, + .alist = th500_mss_channel_alist, + .alist_size = ARRAY_SIZE(th500_mss_channel_alist), + .fake_registers = NULL, + }, + { + .element_type = IP_ELEMENT_PERFMUX, + .element_index_mask = BIT(20), + .element_index = 21U, + .dt_mmio = NULL, + .name = {'\0'}, + .start_abs_pa = addr_map_mc20_base_r(), + .end_abs_pa = addr_map_mc20_limit_r(), + .start_pa = addr_map_mc20_base_r(), + .end_pa = addr_map_mc20_limit_r(), + .base_pa = 0ULL, + .alist = th500_mss_channel_alist, + .alist_size = ARRAY_SIZE(th500_mss_channel_alist), + .fake_registers = NULL, + }, + { + .element_type = IP_ELEMENT_PERFMUX, + .element_index_mask = BIT(21), + .element_index = 22U, + .dt_mmio = NULL, + .name = {'\0'}, + .start_abs_pa = addr_map_mc21_base_r(), + .end_abs_pa = addr_map_mc21_limit_r(), + .start_pa = addr_map_mc21_base_r(), + .end_pa = addr_map_mc21_limit_r(), + .base_pa = 0ULL, + .alist = th500_mss_channel_alist, + .alist_size = ARRAY_SIZE(th500_mss_channel_alist), + .fake_registers = NULL, + }, + { + .element_type = IP_ELEMENT_PERFMUX, + .element_index_mask = BIT(22), + .element_index = 23U, + .dt_mmio = NULL, + .name = {'\0'}, + .start_abs_pa = addr_map_mc22_base_r(), + .end_abs_pa = addr_map_mc22_limit_r(), + .start_pa = addr_map_mc22_base_r(), + .end_pa = addr_map_mc22_limit_r(), + .base_pa = 0ULL, + .alist = th500_mss_channel_alist, + .alist_size = ARRAY_SIZE(th500_mss_channel_alist), + .fake_registers = NULL, + }, + { + .element_type = IP_ELEMENT_PERFMUX, + .element_index_mask = BIT(23), + .element_index = 24U, + .dt_mmio = NULL, + .name = {'\0'}, + .start_abs_pa = addr_map_mc23_base_r(), + .end_abs_pa = addr_map_mc23_limit_r(), + .start_pa = addr_map_mc23_base_r(), + .end_pa = addr_map_mc23_limit_r(), + .base_pa = 0ULL, + .alist = th500_mss_channel_alist, + .alist_size = ARRAY_SIZE(th500_mss_channel_alist), + .fake_registers = NULL, + }, + { + .element_type = IP_ELEMENT_PERFMUX, + .element_index_mask = BIT(24), + .element_index = 25U, + .dt_mmio = NULL, + .name = {'\0'}, + .start_abs_pa = addr_map_mc24_base_r(), + .end_abs_pa = addr_map_mc24_limit_r(), + .start_pa = addr_map_mc24_base_r(), + .end_pa = addr_map_mc24_limit_r(), + .base_pa = 0ULL, + .alist = th500_mss_channel_alist, + .alist_size = ARRAY_SIZE(th500_mss_channel_alist), + .fake_registers = NULL, + }, + { + .element_type = IP_ELEMENT_PERFMUX, + .element_index_mask = BIT(25), + .element_index = 26U, + .dt_mmio = NULL, + .name = {'\0'}, + .start_abs_pa = addr_map_mc25_base_r(), + .end_abs_pa = addr_map_mc25_limit_r(), + .start_pa = addr_map_mc25_base_r(), + .end_pa = addr_map_mc25_limit_r(), + .base_pa = 0ULL, + .alist = th500_mss_channel_alist, + .alist_size = ARRAY_SIZE(th500_mss_channel_alist), + .fake_registers = NULL, + }, + { + .element_type = IP_ELEMENT_PERFMUX, + .element_index_mask = BIT(26), + .element_index = 27U, + .dt_mmio = NULL, + .name = {'\0'}, + .start_abs_pa = addr_map_mc26_base_r(), + .end_abs_pa = addr_map_mc26_limit_r(), + .start_pa = addr_map_mc26_base_r(), + .end_pa = addr_map_mc26_limit_r(), + .base_pa = 0ULL, + .alist = th500_mss_channel_alist, + .alist_size = ARRAY_SIZE(th500_mss_channel_alist), + .fake_registers = NULL, + }, + { + .element_type = IP_ELEMENT_PERFMUX, + .element_index_mask = BIT(27), + .element_index = 28U, + .dt_mmio = NULL, + .name = {'\0'}, + .start_abs_pa = addr_map_mc27_base_r(), + .end_abs_pa = addr_map_mc27_limit_r(), + .start_pa = addr_map_mc27_base_r(), + .end_pa = addr_map_mc27_limit_r(), + .base_pa = 0ULL, + .alist = th500_mss_channel_alist, + .alist_size = ARRAY_SIZE(th500_mss_channel_alist), + .fake_registers = NULL, + }, + { + .element_type = IP_ELEMENT_PERFMUX, + .element_index_mask = BIT(28), + .element_index = 29U, + .dt_mmio = NULL, + .name = {'\0'}, + .start_abs_pa = addr_map_mc28_base_r(), + .end_abs_pa = addr_map_mc28_limit_r(), + .start_pa = addr_map_mc28_base_r(), + .end_pa = addr_map_mc28_limit_r(), + .base_pa = 0ULL, + .alist = th500_mss_channel_alist, + .alist_size = ARRAY_SIZE(th500_mss_channel_alist), + .fake_registers = NULL, + }, + { + .element_type = IP_ELEMENT_PERFMUX, + .element_index_mask = BIT(29), + .element_index = 30U, + .dt_mmio = NULL, + .name = {'\0'}, + .start_abs_pa = addr_map_mc29_base_r(), + .end_abs_pa = addr_map_mc29_limit_r(), + .start_pa = addr_map_mc29_base_r(), + .end_pa = addr_map_mc29_limit_r(), + .base_pa = 0ULL, + .alist = th500_mss_channel_alist, + .alist_size = ARRAY_SIZE(th500_mss_channel_alist), + .fake_registers = NULL, + }, + { + .element_type = IP_ELEMENT_PERFMUX, + .element_index_mask = BIT(30), + .element_index = 31U, + .dt_mmio = NULL, + .name = {'\0'}, + .start_abs_pa = addr_map_mc30_base_r(), + .end_abs_pa = addr_map_mc30_limit_r(), + .start_pa = addr_map_mc30_base_r(), + .end_pa = addr_map_mc30_limit_r(), + .base_pa = 0ULL, + .alist = th500_mss_channel_alist, + .alist_size = ARRAY_SIZE(th500_mss_channel_alist), + .fake_registers = NULL, + }, + { + .element_type = IP_ELEMENT_PERFMUX, + .element_index_mask = BIT(31), + .element_index = 32U, + .dt_mmio = NULL, + .name = {'\0'}, + .start_abs_pa = addr_map_mc31_base_r(), + .end_abs_pa = addr_map_mc31_limit_r(), + .start_pa = addr_map_mc31_base_r(), + .end_pa = addr_map_mc31_limit_r(), + .base_pa = 0ULL, + .alist = th500_mss_channel_alist, + .alist_size = ARRAY_SIZE(th500_mss_channel_alist), + .fake_registers = NULL, + }, +}; + +static struct hwpm_ip_aperture th500_mss_channel_inst0_broadcast_element_static_array[ + TH500_HWPM_IP_MSS_CHANNEL_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_mss_channel_alist, + .alist_size = ARRAY_SIZE(th500_mss_channel_alist), + .fake_registers = NULL, + }, +}; + +/* IP instance array */ +static struct hwpm_ip_inst th500_mss_channel_inst_static_array[ + TH500_HWPM_IP_MSS_CHANNEL_NUM_INSTANCES] = { + { + .hw_inst_mask = BIT(0), + .num_core_elements_per_inst = + TH500_HWPM_IP_MSS_CHANNEL_NUM_CORE_ELEMENT_PER_INST, + .element_info = { + /* + * Instance info corresponding to + * TEGRA_HWPM_APERTURE_TYPE_PERFMUX + */ + { + .num_element_per_inst = + TH500_HWPM_IP_MSS_CHANNEL_NUM_PERFMUX_PER_INST, + .element_static_array = + th500_mss_channel_inst0_perfmux_element_static_array, + /* NOTE: range should be in ascending order */ + .range_start = addr_map_mc0_base_r(), + .range_end = addr_map_mc31_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_MSS_CHANNEL_NUM_BROADCAST_PER_INST, + .element_static_array = + th500_mss_channel_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_MSS_CHANNEL_NUM_PERFMON_PER_INST, + .element_static_array = + th500_mss_channel_inst0_perfmon_element_static_array, + .range_start = addr_map_rpg_pm_msschannel0_base_r(), + .range_end = addr_map_rpg_pm_msschannel31_limit_r(), + .element_stride = addr_map_rpg_pm_msschannel0_limit_r() - + addr_map_rpg_pm_msschannel0_base_r() + 1ULL, + .element_slots = 0U, + .element_arr = NULL, + }, + }, + + .ip_ops = { + .ip_dev = NULL, + .hwpm_ip_pm = NULL, + .hwpm_ip_reg_op = NULL, + }, + + .element_fs_mask = 0U, + }, +}; + +/* IP structure */ +struct hwpm_ip th500_hwpm_ip_mss_channel = { + .num_instances = TH500_HWPM_IP_MSS_CHANNEL_NUM_INSTANCES, + .ip_inst_static_array = th500_mss_channel_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_mc31_limit_r(), + .inst_stride = addr_map_mc31_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_msschannel0_base_r(), + .range_end = addr_map_rpg_pm_msschannel31_limit_r(), + .inst_stride = addr_map_rpg_pm_msschannel31_limit_r() - + addr_map_rpg_pm_msschannel0_base_r() + 1ULL, + .inst_slots = 0U, + .inst_arr = NULL, + }, + }, + + .dependent_fuse_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/mss_channel/th500_mss_channel.h b/drivers/tegra/hwpm/hal/th500/soc/ip/mss_channel/th500_mss_channel.h new file mode 100644 index 0000000..6f191d9 --- /dev/null +++ b/drivers/tegra/hwpm/hal/th500/soc/ip/mss_channel/th500_mss_channel.h @@ -0,0 +1,33 @@ +/* + * Copyright (c) 2022-2023, NVIDIA CORPORATION & AFFILIATES. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + */ + +#ifndef TH500_HWPM_IP_MSS_CHANNEL_H +#define TH500_HWPM_IP_MSS_CHANNEL_H + +#if defined(CONFIG_TH500_HWPM_IP_MSS_CHANNEL) +#define TH500_HWPM_ACTIVE_IP_MSS_CHANNEL TH500_HWPM_IP_MSS_CHANNEL, + +/* This data should ideally be available in HW headers */ +#define TH500_HWPM_IP_MSS_CHANNEL_NUM_INSTANCES 1U +#define TH500_HWPM_IP_MSS_CHANNEL_NUM_CORE_ELEMENT_PER_INST 32U +#define TH500_HWPM_IP_MSS_CHANNEL_NUM_PERFMON_PER_INST 32U +#define TH500_HWPM_IP_MSS_CHANNEL_NUM_PERFMUX_PER_INST 32U +#define TH500_HWPM_IP_MSS_CHANNEL_NUM_BROADCAST_PER_INST 1U + +extern struct hwpm_ip th500_hwpm_ip_mss_channel; + +#else +#define TH500_HWPM_ACTIVE_IP_MSS_CHANNEL +#endif + +#endif /* TH500_HWPM_IP_MSS_CHANNEL_H */ diff --git a/drivers/tegra/hwpm/hal/th500/soc/ip/pma/th500_pma.c b/drivers/tegra/hwpm/hal/th500/soc/ip/pma/th500_pma.c new file mode 100644 index 0000000..9b67d05 --- /dev/null +++ b/drivers/tegra/hwpm/hal/th500/soc/ip/pma/th500_pma.c @@ -0,0 +1,185 @@ +// SPDX-License-Identifier: MIT +/* SPDX-FileCopyrightText: Copyright (c) 2022-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. + */ + +#include "th500_pma.h" + +#include +#include +#include +#include + +static struct hwpm_ip_aperture th500_pma_inst0_perfmon_element_static_array[ + TH500_HWPM_IP_PMA_NUM_PERFMON_PER_INST] = { + { + .element_type = HWPM_ELEMENT_PERFMON, + .element_index_mask = BIT(0), + .element_index = 0U, + .dt_mmio = NULL, + .name = "perfmon_sys0", + .device_index = TH500_SYS0_PERFMON_DEVICE_NODE_INDEX, + .start_abs_pa = addr_map_rpg_pm_sys0_base_r(), + .end_abs_pa = addr_map_rpg_pm_sys0_limit_r(), + .start_pa = addr_map_rpg_pm_sys0_base_r(), + .end_pa = addr_map_rpg_pm_sys0_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_pma_inst0_perfmux_element_static_array[ + TH500_HWPM_IP_PMA_NUM_PERFMUX_PER_INST] = { + { + .element_type = HWPM_ELEMENT_PERFMUX, + .element_index_mask = BIT(0), + .element_index = 0U, + .dt_mmio = NULL, + .name = "pma", + .device_index = TH500_PMA_DEVICE_NODE_INDEX, + .start_abs_pa = addr_map_pma_base_r(), + .end_abs_pa = addr_map_pma_limit_r(), + .start_pa = addr_map_pma_base_r(), + .end_pa = addr_map_pma_limit_r(), + .base_pa = addr_map_pma_base_r(), + .alist = th500_pma_res_pma_alist, + .alist_size = ARRAY_SIZE(th500_pma_res_pma_alist), + .fake_registers = NULL, + }, +}; + +/* IP instance array */ +static struct hwpm_ip_inst th500_pma_inst_static_array[ + TH500_HWPM_IP_PMA_NUM_INSTANCES] = { + { + .hw_inst_mask = BIT(0), + .num_core_elements_per_inst = + TH500_HWPM_IP_PMA_NUM_CORE_ELEMENT_PER_INST, + .element_info = { + /* + * Instance info corresponding to + * TEGRA_HWPM_APERTURE_TYPE_PERFMUX + */ + { + .num_element_per_inst = + TH500_HWPM_IP_PMA_NUM_PERFMUX_PER_INST, + .element_static_array = + th500_pma_inst0_perfmux_element_static_array, + .range_start = addr_map_pma_base_r(), + .range_end = addr_map_pma_limit_r(), + .element_stride = addr_map_pma_limit_r() - + addr_map_pma_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_PMA_NUM_BROADCAST_PER_INST, + .element_static_array = NULL, + .range_start = 0ULL, + .range_end = 0ULL, + .element_stride = 0ULL, + .element_slots = 0U, + .element_arr = NULL, + }, + /* + * Instance info corresponding to + * TEGRA_HWPM_APERTURE_TYPE_PERFMON + */ + { + .num_element_per_inst = + TH500_HWPM_IP_PMA_NUM_PERFMON_PER_INST, + .element_static_array = + th500_pma_inst0_perfmon_element_static_array, + .range_start = addr_map_rpg_pm_sys0_base_r(), + .range_end = addr_map_rpg_pm_sys0_limit_r(), + .element_stride = addr_map_rpg_pm_sys0_limit_r() - + addr_map_rpg_pm_sys0_base_r() + 1ULL, + .element_slots = 0U, + .element_arr = NULL, + }, + }, + + .ip_ops = { + .ip_dev = NULL, + .hwpm_ip_pm = NULL, + .hwpm_ip_reg_op = NULL, + }, + + .element_fs_mask = 0x1U, + }, +}; + +/* IP structure */ +struct hwpm_ip th500_hwpm_ip_pma = { + .num_instances = TH500_HWPM_IP_PMA_NUM_INSTANCES, + .ip_inst_static_array = th500_pma_inst_static_array, + + .inst_aperture_info = { + /* + * Instance info corresponding to + * TEGRA_HWPM_APERTURE_TYPE_PERFMUX + */ + { + .range_start = addr_map_pma_base_r(), + .range_end = addr_map_pma_limit_r(), + .inst_stride = addr_map_pma_limit_r() - + addr_map_pma_base_r() + 1ULL, + .inst_slots = 0U, + .inst_arr = NULL, + }, + /* + * Instance info corresponding to + * TEGRA_HWPM_APERTURE_TYPE_BROADCAST + */ + { + .range_start = 0ULL, + .range_end = 0ULL, + .inst_stride = 0ULL, + .inst_slots = 0U, + .inst_arr = NULL, + }, + /* + * Instance info corresponding to + * TEGRA_HWPM_APERTURE_TYPE_PERFMON + */ + { + .range_start = addr_map_rpg_pm_sys0_base_r(), + .range_end = addr_map_rpg_pm_sys0_limit_r(), + .inst_stride = addr_map_rpg_pm_sys0_limit_r() - + addr_map_rpg_pm_sys0_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 = 0x1U, + .resource_status = TEGRA_HWPM_RESOURCE_STATUS_VALID, + .reserved = false, +}; diff --git a/drivers/tegra/hwpm/hal/th500/soc/ip/pma/th500_pma.h b/drivers/tegra/hwpm/hal/th500/soc/ip/pma/th500_pma.h new file mode 100644 index 0000000..6efd71a --- /dev/null +++ b/drivers/tegra/hwpm/hal/th500/soc/ip/pma/th500_pma.h @@ -0,0 +1,37 @@ +/* SPDX-License-Identifier: MIT */ +/* SPDX-FileCopyrightText: Copyright (c) 2022-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. + */ + +#ifndef TH500_HWPM_IP_PMA_H +#define TH500_HWPM_IP_PMA_H + +#define TH500_HWPM_ACTIVE_IP_PMA TH500_HWPM_IP_PMA, + +/* This data should ideally be available in HW headers */ +#define TH500_HWPM_IP_PMA_NUM_INSTANCES 1U +#define TH500_HWPM_IP_PMA_NUM_CORE_ELEMENT_PER_INST 1U +#define TH500_HWPM_IP_PMA_NUM_PERFMON_PER_INST 1U +#define TH500_HWPM_IP_PMA_NUM_PERFMUX_PER_INST 1U +#define TH500_HWPM_IP_PMA_NUM_BROADCAST_PER_INST 0U + +extern struct hwpm_ip th500_hwpm_ip_pma; + +#endif /* TH500_HWPM_IP_PMA_H */ diff --git a/drivers/tegra/hwpm/hal/th500/soc/ip/rtr/th500_rtr.c b/drivers/tegra/hwpm/hal/th500/soc/ip/rtr/th500_rtr.c new file mode 100644 index 0000000..f099eee --- /dev/null +++ b/drivers/tegra/hwpm/hal/th500/soc/ip/rtr/th500_rtr.c @@ -0,0 +1,259 @@ +// SPDX-License-Identifier: MIT +/* SPDX-FileCopyrightText: Copyright (c) 2022-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. + */ + +#include "th500_rtr.h" + +#include +#include +#include +#include + +/* RTR aperture should be placed in instance TH500_HWPM_IP_RTR_STATIC_RTR_INST */ +static struct hwpm_ip_aperture th500_rtr_inst0_perfmux_element_static_array[ + TH500_HWPM_IP_RTR_NUM_PERFMUX_PER_INST] = { + { + .element_type = HWPM_ELEMENT_PERFMUX, + .element_index_mask = BIT(0), + .element_index = 0U, + .dt_mmio = NULL, + .name = "rtr", + .device_index = TH500_RTR_DEVICE_NODE_INDEX, + .start_abs_pa = addr_map_rtr_base_r(), + .end_abs_pa = addr_map_rtr_limit_r(), + .start_pa = addr_map_rtr_base_r(), + .end_pa = addr_map_rtr_limit_r(), + .base_pa = addr_map_rtr_base_r(), + .alist = th500_rtr_alist, + .alist_size = ARRAY_SIZE(th500_rtr_alist), + .fake_registers = NULL, + }, +}; + +/* PMA from RTR perspective */ +/* PMA aperture should be placed in instance TH500_HWPM_IP_RTR_STATIC_PMA_INST */ +static struct hwpm_ip_aperture th500_rtr_inst1_perfmux_element_static_array[ + TH500_HWPM_IP_RTR_NUM_PERFMUX_PER_INST] = { + { + .element_type = HWPM_ELEMENT_PERFMUX, + .element_index_mask = BIT(0), + .element_index = 0U, + .dt_mmio = NULL, + .name = "pma", + .device_index = TH500_PMA_DEVICE_NODE_INDEX, + .start_abs_pa = addr_map_pma_base_r(), + .end_abs_pa = addr_map_pma_limit_r(), + .start_pa = addr_map_pma_base_r(), + .end_pa = addr_map_pma_limit_r(), + .base_pa = addr_map_pma_base_r(), + .alist = th500_pma_res_cmd_slice_rtr_alist, + .alist_size = ARRAY_SIZE(th500_pma_res_cmd_slice_rtr_alist), + .fake_registers = NULL, + }, +}; + +/* IP instance array */ +static struct hwpm_ip_inst th500_rtr_inst_static_array[ + TH500_HWPM_IP_RTR_NUM_INSTANCES] = { + { + .hw_inst_mask = BIT(0), + .num_core_elements_per_inst = + TH500_HWPM_IP_RTR_NUM_CORE_ELEMENT_PER_INST, + .element_info = { + /* + * Instance info corresponding to + * TEGRA_HWPM_APERTURE_TYPE_PERFMUX + */ + { + .num_element_per_inst = + TH500_HWPM_IP_RTR_NUM_PERFMUX_PER_INST, + .element_static_array = + th500_rtr_inst0_perfmux_element_static_array, + .range_start = addr_map_rtr_base_r(), + .range_end = addr_map_rtr_limit_r(), + .element_stride = addr_map_rtr_limit_r() - + addr_map_rtr_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_RTR_NUM_BROADCAST_PER_INST, + .element_static_array = NULL, + .range_start = 0ULL, + .range_end = 0ULL, + .element_stride = 0ULL, + .element_slots = 0U, + .element_arr = NULL, + }, + /* + * Instance info corresponding to + * TEGRA_HWPM_APERTURE_TYPE_PERFMON + */ + { + .num_element_per_inst = + TH500_HWPM_IP_RTR_NUM_PERFMON_PER_INST, + .element_static_array = NULL, + .range_start = 0ULL, + .range_end = 0ULL, + .element_stride = 0ULL, + .element_slots = 0U, + .element_arr = NULL, + }, + }, + + .ip_ops = { + .ip_dev = NULL, + .hwpm_ip_pm = NULL, + .hwpm_ip_reg_op = NULL, + }, + + .element_fs_mask = 0x1U, + }, + { + .hw_inst_mask = BIT(1), + .num_core_elements_per_inst = + TH500_HWPM_IP_RTR_NUM_CORE_ELEMENT_PER_INST, + .element_info = { + /* + * Instance info corresponding to + * TEGRA_HWPM_APERTURE_TYPE_PERFMUX + */ + { + .num_element_per_inst = + TH500_HWPM_IP_RTR_NUM_PERFMUX_PER_INST, + .element_static_array = + th500_rtr_inst1_perfmux_element_static_array, + .range_start = addr_map_pma_base_r(), + .range_end = addr_map_pma_limit_r(), + .element_stride = addr_map_pma_limit_r() - + addr_map_pma_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_RTR_NUM_BROADCAST_PER_INST, + .element_static_array = NULL, + .range_start = 0ULL, + .range_end = 0ULL, + .element_stride = 0ULL, + .element_slots = 0U, + .element_arr = NULL, + }, + /* + * Instance info corresponding to + * TEGRA_HWPM_APERTURE_TYPE_PERFMON + */ + { + .num_element_per_inst = + TH500_HWPM_IP_RTR_NUM_PERFMON_PER_INST, + .element_static_array = NULL, + .range_start = 0ULL, + .range_end = 0ULL, + .element_stride = 0ULL, + + .element_slots = 0U, + .element_arr = NULL, + }, + }, + + .ip_ops = { + .ip_dev = NULL, + .hwpm_ip_pm = NULL, + .hwpm_ip_reg_op = NULL, + }, + + .element_fs_mask = 0x1U, + }, +}; + +/* IP structure */ +struct hwpm_ip th500_hwpm_ip_rtr = { + .num_instances = TH500_HWPM_IP_RTR_NUM_INSTANCES, + .ip_inst_static_array = th500_rtr_inst_static_array, + + .inst_aperture_info = { + /* + * Instance info corresponding to + * TEGRA_HWPM_APERTURE_TYPE_PERFMUX + */ + { + /* + * PMA block is 0x2000 wide and RTR block is 0x1000 wide + * Expected facts: + * - PMA should be referred as a single entity + * - RTR IP instance array should have 2 slots(PMA, RTR) + * + * To ensure that the inst_slots are computed correctly + * as 2 slots, the instance range for perfmux aperture + * needs to be twice the PMA block. + */ + .range_start = addr_map_pma_base_r(), + .range_end = addr_map_pma_limit_r() + + (addr_map_pma_limit_r() - + addr_map_pma_base_r() + 1ULL), + /* Use PMA stride as it is larger block than RTR */ + .inst_stride = addr_map_pma_limit_r() - + addr_map_pma_base_r() + 1ULL, + .inst_slots = 0U, + .inst_arr = NULL, + }, + /* + * Instance info corresponding to + * TEGRA_HWPM_APERTURE_TYPE_BROADCAST + */ + { + .range_start = 0ULL, + .range_end = 0ULL, + .inst_stride = 0ULL, + .inst_slots = 0U, + .inst_arr = NULL, + }, + /* + * Instance info corresponding to + * TEGRA_HWPM_APERTURE_TYPE_PERFMON + */ + { + .range_start = 0ULL, + .range_end = 0ULL, + .inst_stride = 0ULL, + .inst_slots = 0U, + .inst_arr = NULL, + }, + }, + + .dependent_fuse_mask = 0U, + .override_enable = false, + /* RTR is defined as 2 instance IP corresponding to router and pma */ + /* Set this mask to indicate that instances are available */ + .inst_fs_mask = 0x3U, + .resource_status = TEGRA_HWPM_RESOURCE_STATUS_VALID, + .reserved = false, +}; diff --git a/drivers/tegra/hwpm/hal/th500/soc/ip/rtr/th500_rtr.h b/drivers/tegra/hwpm/hal/th500/soc/ip/rtr/th500_rtr.h new file mode 100644 index 0000000..a1029c0 --- /dev/null +++ b/drivers/tegra/hwpm/hal/th500/soc/ip/rtr/th500_rtr.h @@ -0,0 +1,41 @@ +/* SPDX-License-Identifier: MIT */ +/* SPDX-FileCopyrightText: Copyright (c) 2022-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. + */ + +#ifndef TH500_HWPM_IP_RTR_H +#define TH500_HWPM_IP_RTR_H + +#define TH500_HWPM_ACTIVE_IP_RTR TH500_HWPM_IP_RTR, + +/* This data should ideally be available in HW headers */ +#define TH500_HWPM_IP_RTR_NUM_INSTANCES 2U +#define TH500_HWPM_IP_RTR_NUM_CORE_ELEMENT_PER_INST 1U +#define TH500_HWPM_IP_RTR_NUM_PERFMON_PER_INST 0U +#define TH500_HWPM_IP_RTR_NUM_PERFMUX_PER_INST 1U +#define TH500_HWPM_IP_RTR_NUM_BROADCAST_PER_INST 0U + +#define TH500_HWPM_IP_RTR_STATIC_RTR_INST 0U +#define TH500_HWPM_IP_RTR_STATIC_PMA_INST 1U +#define TH500_HWPM_IP_RTR_PERFMUX_INDEX 0U + +extern struct hwpm_ip th500_hwpm_ip_rtr; + +#endif /* TH500_HWPM_IP_RTR_H */ diff --git a/drivers/tegra/hwpm/hal/th500/soc/th500_soc_aperture.c b/drivers/tegra/hwpm/hal/th500/soc/th500_soc_aperture.c new file mode 100644 index 0000000..f9cc32c --- /dev/null +++ b/drivers/tegra/hwpm/hal/th500/soc/th500_soc_aperture.c @@ -0,0 +1,450 @@ +// SPDX-License-Identifier: MIT +/* SPDX-FileCopyrightText: Copyright (c) 2022-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. + */ + +#include +#include +#include +#include +#include +#include + +#include +#include + +int th500_hwpm_soc_check_status(struct tegra_soc_hwpm *hwpm) +{ + int err = 0; + u32 reg_val = 0U; + struct tegra_soc_hwpm_chip *active_chip = hwpm->active_chip; + struct hwpm_ip *chip_ip = active_chip->chip_ips[ + active_chip->get_rtr_int_idx(hwpm)]; + struct hwpm_ip_inst *ip_inst_rtr = &chip_ip->ip_inst_static_array[ + TH500_HWPM_IP_RTR_STATIC_RTR_INST]; + struct hwpm_ip_inst *ip_inst_pma = &chip_ip->ip_inst_static_array[ + TH500_HWPM_IP_RTR_STATIC_PMA_INST]; + struct hwpm_ip_aperture *rtr_perfmux = &ip_inst_rtr->element_info[ + TEGRA_HWPM_APERTURE_TYPE_PERFMUX].element_static_array[ + TH500_HWPM_IP_RTR_PERFMUX_INDEX]; + struct hwpm_ip_aperture *pma_perfmux = &ip_inst_pma->element_info[ + TEGRA_HWPM_APERTURE_TYPE_PERFMUX].element_static_array[ + TH500_HWPM_IP_RTR_PERFMUX_INDEX]; + + tegra_hwpm_fn(hwpm, " "); + + /* Check ROUTER state */ + err = tegra_hwpm_readl(hwpm, rtr_perfmux, + pmmsys_sys0router_enginestatus_r(), ®_val); + if (err != 0) { + tegra_hwpm_err(hwpm, "hwpm read failed"); + return err; + } + + if (pmmsys_sys0router_enginestatus_status_v(reg_val) != + pmmsys_sys0router_enginestatus_status_empty_v()) { + tegra_hwpm_err(hwpm, "Router not ready value 0x%x", reg_val); + return -EINVAL; + } + + /* Check PMA state */ + err = tegra_hwpm_readl(hwpm, pma_perfmux, + pmasys_channel_status_r(0), ®_val); + if (err != 0) { + tegra_hwpm_err(hwpm, "hwpm read failed"); + return err; + } + + if ((reg_val & pmasys_channel_status_engine_status_m()) != + pmasys_channel_status_engine_status_empty_f()) { + tegra_hwpm_err(hwpm, "PMA not ready value 0x%x", reg_val); + return -EINVAL; + } + + return err; +} + +int th500_hwpm_soc_disable_triggers(struct tegra_soc_hwpm *hwpm) +{ + int err = 0; + u32 reg_val = 0U; + u32 sleep_msecs = 100; + struct tegra_hwpm_timeout timeout; + struct tegra_soc_hwpm_chip *active_chip = hwpm->active_chip; + struct hwpm_ip *chip_ip = active_chip->chip_ips[ + active_chip->get_rtr_int_idx(hwpm)]; + struct hwpm_ip_inst *ip_inst_rtr = &chip_ip->ip_inst_static_array[ + TH500_HWPM_IP_RTR_STATIC_RTR_INST]; + struct hwpm_ip_inst *ip_inst_pma = &chip_ip->ip_inst_static_array[ + TH500_HWPM_IP_RTR_STATIC_PMA_INST]; + struct hwpm_ip_aperture *rtr_perfmux = &ip_inst_rtr->element_info[ + TEGRA_HWPM_APERTURE_TYPE_PERFMUX].element_static_array[ + TH500_HWPM_IP_RTR_PERFMUX_INDEX]; + struct hwpm_ip_aperture *pma_perfmux = &ip_inst_pma->element_info[ + TEGRA_HWPM_APERTURE_TYPE_PERFMUX].element_static_array[ + TH500_HWPM_IP_RTR_PERFMUX_INDEX]; + + tegra_hwpm_fn(hwpm, " "); + + /* Disable PMA triggers */ + err = tegra_hwpm_readl(hwpm, pma_perfmux, + pmasys_command_slice_trigger_config_user_r(0), ®_val); + if (err != 0) { + tegra_hwpm_err(hwpm, "hwpm read failed"); + return err; + } + reg_val = set_field(reg_val, + pmasys_command_slice_trigger_config_user_pma_pulse_m(), + pmasys_command_slice_trigger_config_user_pma_pulse_disable_f()); + err = tegra_hwpm_writel(hwpm, pma_perfmux, + pmasys_command_slice_trigger_config_user_r(0), reg_val); + if (err != 0) { + tegra_hwpm_err(hwpm, "hwpm write failed"); + return err; + } + + /* Wait for PERFMONs to idle */ + err = tegra_hwpm_timeout_init(hwpm, &timeout, 10U); + if (err != 0) { + tegra_hwpm_err(hwpm, "hwpm timeout init failed"); + return err; + } + + do { + err = tegra_hwpm_readl(hwpm, rtr_perfmux, + pmmsys_sysrouter_enginestatus_r(), ®_val); + if (err != 0) { + tegra_hwpm_err(hwpm, "hwpm read failed"); + return err; + } + tegra_hwpm_msleep(sleep_msecs); + } while ((pmmsys_sysrouter_enginestatus_merged_perfmon_status_v( + reg_val) != 0U) && + (tegra_hwpm_timeout_expired(hwpm, &timeout) == 0)); + + if (pmmsys_sysrouter_enginestatus_merged_perfmon_status_v( + reg_val) != 0U) { + tegra_hwpm_err(hwpm, "Timeout expired for " + "NV_PERF_PMMSYS_SYSROUTER_ENGINESTATUS_PERFMON_STATUS"); + return -ETIMEDOUT; + } + + /* Wait for ROUTER to idle */ + err = tegra_hwpm_timeout_init(hwpm, &timeout, 10U); + if (err != 0) { + tegra_hwpm_err(hwpm, "hwpm timeout init failed"); + return err; + } + + do { + err = tegra_hwpm_readl(hwpm, rtr_perfmux, + pmmsys_sys0router_enginestatus_r(), ®_val); + if (err != 0) { + tegra_hwpm_err(hwpm, "hwpm read failed"); + return err; + } + tegra_hwpm_msleep(sleep_msecs); + } while ((pmmsys_sys0router_enginestatus_status_v(reg_val) != + pmmsys_sys0router_enginestatus_status_empty_v()) && + (tegra_hwpm_timeout_expired(hwpm, &timeout) == 0)); + + if (pmmsys_sys0router_enginestatus_status_v(reg_val) != + pmmsys_sys0router_enginestatus_status_empty_v()) { + tegra_hwpm_err(hwpm, "Timeout expired for " + "NV_PERF_PMMSYS_SYS0ROUTER_ENGINESTATUS_STATUS"); + return -ETIMEDOUT; + } + + /* Wait for PMA to idle */ + err = tegra_hwpm_timeout_init(hwpm, &timeout, 10U); + if (err != 0) { + tegra_hwpm_err(hwpm, "hwpm timeout init failed"); + return err; + } + + do { + err = tegra_hwpm_readl(hwpm, pma_perfmux, + pmasys_channel_status_r(0), ®_val); + if (err != 0) { + tegra_hwpm_err(hwpm, "hwpm read failed"); + return err; + } + tegra_hwpm_msleep(sleep_msecs); + } while (((reg_val & pmasys_channel_status_engine_status_m()) != + pmasys_channel_status_engine_status_empty_f()) && + (tegra_hwpm_timeout_expired(hwpm, &timeout) == 0)); + + if ((reg_val & pmasys_channel_status_engine_status_m()) != + pmasys_channel_status_engine_status_empty_f()) { + tegra_hwpm_err(hwpm, "Timeout expired for " + "NV_PERF_PMASYS_CHANNEL_STATUS"); + return -ETIMEDOUT; + } + + return err; +} + +int th500_hwpm_soc_init_prod_values(struct tegra_soc_hwpm *hwpm) +{ + int err = 0; + u32 reg_val = 0U; + struct tegra_soc_hwpm_chip *active_chip = hwpm->active_chip; + struct hwpm_ip *chip_ip = active_chip->chip_ips[ + active_chip->get_rtr_int_idx(hwpm)]; + struct hwpm_ip_inst *ip_inst_rtr = &chip_ip->ip_inst_static_array[ + TH500_HWPM_IP_RTR_STATIC_RTR_INST]; + struct hwpm_ip_inst *ip_inst_pma = &chip_ip->ip_inst_static_array[ + TH500_HWPM_IP_RTR_STATIC_PMA_INST]; + struct hwpm_ip_aperture *rtr_perfmux = &ip_inst_rtr->element_info[ + TEGRA_HWPM_APERTURE_TYPE_PERFMUX].element_static_array[ + TH500_HWPM_IP_RTR_PERFMUX_INDEX]; + struct hwpm_ip_aperture *pma_perfmux = &ip_inst_pma->element_info[ + TEGRA_HWPM_APERTURE_TYPE_PERFMUX].element_static_array[ + TH500_HWPM_IP_RTR_PERFMUX_INDEX]; + + tegra_hwpm_fn(hwpm, " "); + + err = tegra_hwpm_readl(hwpm, pma_perfmux, + pmasys_channel_config_user_r(0), ®_val); + if (err != 0) { + tegra_hwpm_err(hwpm, "hwpm read failed"); + return err; + } + reg_val = set_field(reg_val, + pmasys_channel_config_user_coalesce_timeout_cycles_m(), + pmasys_channel_config_user_coalesce_timeout_cycles__prod_f()); + err = tegra_hwpm_writel(hwpm, pma_perfmux, + pmasys_channel_config_user_r(0), reg_val); + if (err != 0) { + tegra_hwpm_err(hwpm, "hwpm write failed"); + return err; + } + + err = tegra_hwpm_readl(hwpm, pma_perfmux, pmasys_cg2_r(), ®_val); + if (err != 0) { + tegra_hwpm_err(hwpm, "hwpm read failed"); + return err; + } + reg_val = set_field(reg_val, pmasys_cg2_slcg_m(), + pmasys_cg2_slcg__prod_f()); + err = tegra_hwpm_writel(hwpm, pma_perfmux, pmasys_cg2_r(), reg_val); + if (err != 0) { + tegra_hwpm_err(hwpm, "hwpm write failed"); + return err; + } + + err = tegra_hwpm_readl(hwpm, rtr_perfmux, + pmmsys_sys0router_cg1_secure_r(), ®_val); + if (err != 0) { + tegra_hwpm_err(hwpm, "hwpm read failed"); + return err; + } + reg_val = set_field(reg_val, + pmmsys_sys0router_cg1_secure_flcg_perfmon_m(), + pmmsys_sys0router_cg1_secure_flcg_perfmon__prod_f()); + err = tegra_hwpm_writel(hwpm, rtr_perfmux, + pmmsys_sys0router_cg1_secure_r(), reg_val); + if (err != 0) { + tegra_hwpm_err(hwpm, "hwpm write failed"); + return err; + } + + err = tegra_hwpm_readl(hwpm, rtr_perfmux, + pmmsys_sys0router_perfmon_cg2_secure_r(), ®_val); + if (err != 0) { + tegra_hwpm_err(hwpm, "hwpm read failed"); + return err; + } + reg_val = set_field(reg_val, + pmmsys_sys0router_perfmon_cg2_secure_slcg_m(), + pmmsys_sys0router_perfmon_cg2_secure_slcg__prod_f()); + err = tegra_hwpm_writel(hwpm, rtr_perfmux, + pmmsys_sys0router_perfmon_cg2_secure_r(), reg_val); + if (err != 0) { + tegra_hwpm_err(hwpm, "hwpm write failed"); + return err; + } + + return 0; +} + +int th500_hwpm_soc_disable_cg(struct tegra_soc_hwpm *hwpm) +{ + int err = 0; + u32 reg_val = 0U; + struct tegra_soc_hwpm_chip *active_chip = hwpm->active_chip; + struct hwpm_ip *chip_ip = active_chip->chip_ips[ + active_chip->get_rtr_int_idx(hwpm)]; + struct hwpm_ip_inst *ip_inst_rtr = &chip_ip->ip_inst_static_array[ + TH500_HWPM_IP_RTR_STATIC_RTR_INST]; + struct hwpm_ip_inst *ip_inst_pma = &chip_ip->ip_inst_static_array[ + TH500_HWPM_IP_RTR_STATIC_PMA_INST]; + struct hwpm_ip_aperture *rtr_perfmux = &ip_inst_rtr->element_info[ + TEGRA_HWPM_APERTURE_TYPE_PERFMUX].element_static_array[ + TH500_HWPM_IP_RTR_PERFMUX_INDEX]; + struct hwpm_ip_aperture *pma_perfmux = &ip_inst_pma->element_info[ + TEGRA_HWPM_APERTURE_TYPE_PERFMUX].element_static_array[ + TH500_HWPM_IP_RTR_PERFMUX_INDEX]; + + err = tegra_hwpm_readl(hwpm, pma_perfmux, pmasys_cg2_r(), ®_val); + if (err != 0) { + tegra_hwpm_err(hwpm, "hwpm read failed"); + return err; + } + reg_val = set_field(reg_val, pmasys_cg2_slcg_m(), + pmasys_cg2_slcg_disabled_f()); + err = tegra_hwpm_writel(hwpm, pma_perfmux, pmasys_cg2_r(), reg_val); + if (err != 0) { + tegra_hwpm_err(hwpm, "hwpm write failed"); + return err; + } + + err = tegra_hwpm_readl(hwpm, rtr_perfmux, + pmmsys_sys0router_cg1_secure_r(), ®_val); + if (err != 0) { + tegra_hwpm_err(hwpm, "hwpm read failed"); + return err; + } + reg_val = set_field(reg_val, + pmmsys_sys0router_cg1_secure_flcg_perfmon_m(), + pmmsys_sys0router_cg1_secure_flcg_perfmon_disabled_f()); + err = tegra_hwpm_writel(hwpm, rtr_perfmux, + pmmsys_sys0router_cg1_secure_r(), reg_val); + if (err != 0) { + tegra_hwpm_err(hwpm, "hwpm write failed"); + return err; + } + + err = tegra_hwpm_readl(hwpm, rtr_perfmux, + pmmsys_sys0router_perfmon_cg2_secure_r(), ®_val); + if (err != 0) { + tegra_hwpm_err(hwpm, "hwpm read failed"); + return err; + } + reg_val = set_field(reg_val, + pmmsys_sys0router_perfmon_cg2_secure_slcg_m(), + pmmsys_sys0router_perfmon_cg2_secure_slcg_disabled_f()); + err = tegra_hwpm_writel(hwpm, rtr_perfmux, + pmmsys_sys0router_perfmon_cg2_secure_r(), reg_val); + if (err != 0) { + tegra_hwpm_err(hwpm, "hwpm write failed"); + return err; + } + + err = tegra_hwpm_readl(hwpm, rtr_perfmux, + pmmsys_sys0router_cg2_r(), ®_val); + if (err != 0) { + tegra_hwpm_err(hwpm, "hwpm read failed"); + return err; + } + reg_val = set_field(reg_val, + pmmsys_sys0router_cg2_slcg_m(), + pmmsys_sys0router_cg2_slcg_disabled_f()); + err = tegra_hwpm_writel(hwpm, rtr_perfmux, + pmmsys_sys0router_cg2_r(), reg_val); + if (err != 0) { + tegra_hwpm_err(hwpm, "hwpm write failed"); + return err; + } + + return 0; +} + +int th500_hwpm_soc_enable_cg(struct tegra_soc_hwpm *hwpm) +{ + int err = 0; + u32 reg_val = 0U; + struct tegra_soc_hwpm_chip *active_chip = hwpm->active_chip; + struct hwpm_ip *chip_ip = active_chip->chip_ips[ + active_chip->get_rtr_int_idx(hwpm)]; + struct hwpm_ip_inst *ip_inst_rtr = &chip_ip->ip_inst_static_array[ + TH500_HWPM_IP_RTR_STATIC_RTR_INST]; + struct hwpm_ip_inst *ip_inst_pma = &chip_ip->ip_inst_static_array[ + TH500_HWPM_IP_RTR_STATIC_PMA_INST]; + struct hwpm_ip_aperture *rtr_perfmux = &ip_inst_rtr->element_info[ + TEGRA_HWPM_APERTURE_TYPE_PERFMUX].element_static_array[ + TH500_HWPM_IP_RTR_PERFMUX_INDEX]; + struct hwpm_ip_aperture *pma_perfmux = &ip_inst_pma->element_info[ + TEGRA_HWPM_APERTURE_TYPE_PERFMUX].element_static_array[ + TH500_HWPM_IP_RTR_PERFMUX_INDEX]; + + err = tegra_hwpm_readl(hwpm, pma_perfmux, pmasys_cg2_r(), ®_val); + if (err != 0) { + tegra_hwpm_err(hwpm, "hwpm read failed"); + return err; + } + reg_val = set_field(reg_val, pmasys_cg2_slcg_m(), + pmasys_cg2_slcg_enabled_f()); + err = tegra_hwpm_writel(hwpm, pma_perfmux, pmasys_cg2_r(), reg_val); + if (err != 0) { + tegra_hwpm_err(hwpm, "hwpm write failed"); + return err; + } + + err = tegra_hwpm_readl(hwpm, rtr_perfmux, + pmmsys_sys0router_cg1_secure_r(), ®_val); + if (err != 0) { + tegra_hwpm_err(hwpm, "hwpm read failed"); + return err; + } + reg_val = set_field(reg_val, + pmmsys_sys0router_cg1_secure_flcg_perfmon_m(), + pmmsys_sys0router_cg1_secure_flcg_perfmon_enabled_f()); + err = tegra_hwpm_writel(hwpm, rtr_perfmux, + pmmsys_sys0router_cg1_secure_r(), reg_val); + if (err != 0) { + tegra_hwpm_err(hwpm, "hwpm write failed"); + return err; + } + + err = tegra_hwpm_readl(hwpm, rtr_perfmux, + pmmsys_sys0router_perfmon_cg2_secure_r(), ®_val); + if (err != 0) { + tegra_hwpm_err(hwpm, "hwpm read failed"); + return err; + } + reg_val = set_field(reg_val, + pmmsys_sys0router_perfmon_cg2_secure_slcg_m(), + pmmsys_sys0router_perfmon_cg2_secure_slcg_enabled_f()); + err = tegra_hwpm_writel(hwpm, rtr_perfmux, + pmmsys_sys0router_perfmon_cg2_secure_r(), reg_val); + if (err != 0) { + tegra_hwpm_err(hwpm, "hwpm write failed"); + return err; + } + + err = tegra_hwpm_readl(hwpm, rtr_perfmux, + pmmsys_sys0router_cg2_r(), ®_val); + if (err != 0) { + tegra_hwpm_err(hwpm, "hwpm read failed"); + return err; + } + reg_val = set_field(reg_val, + pmmsys_sys0router_cg2_slcg_m(), + pmmsys_sys0router_cg2_slcg_enabled_f()); + err = tegra_hwpm_writel(hwpm, rtr_perfmux, + pmmsys_sys0router_cg2_r(), reg_val); + if (err != 0) { + tegra_hwpm_err(hwpm, "hwpm write failed"); + return err; + } + + return 0; +} diff --git a/drivers/tegra/hwpm/hal/th500/soc/th500_soc_internal.h b/drivers/tegra/hwpm/hal/th500/soc/th500_soc_internal.h new file mode 100644 index 0000000..4b73140 --- /dev/null +++ b/drivers/tegra/hwpm/hal/th500/soc/th500_soc_internal.h @@ -0,0 +1,58 @@ +/* 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. + */ + +#ifndef TH500_HWPM_SOC_INTERNAL_H +#define TH500_HWPM_SOC_INTERNAL_H + +enum tegra_soc_hwpm_ip; +enum tegra_soc_hwpm_resource; +struct tegra_soc_hwpm; +struct hwpm_ip_aperture; + +int th500_hwpm_extract_ip_ops(struct tegra_soc_hwpm *hwpm, + u32 resource_enum, u64 base_address, + struct tegra_hwpm_ip_ops *ip_ops, bool available); +int th500_hwpm_force_enable_ips(struct tegra_soc_hwpm *hwpm); +int th500_hwpm_validate_current_config(struct tegra_soc_hwpm *hwpm); + +int th500_hwpm_soc_init_prod_values(struct tegra_soc_hwpm *hwpm); +int th500_hwpm_soc_disable_cg(struct tegra_soc_hwpm *hwpm); +int th500_hwpm_soc_enable_cg(struct tegra_soc_hwpm *hwpm); + +int th500_hwpm_soc_check_status(struct tegra_soc_hwpm *hwpm); +int th500_hwpm_soc_disable_triggers(struct tegra_soc_hwpm *hwpm); +int th500_hwpm_soc_perfmon_enable(struct tegra_soc_hwpm *hwpm, + struct hwpm_ip_aperture *perfmon); +int th500_hwpm_soc_perfmon_disable(struct tegra_soc_hwpm *hwpm, + struct hwpm_ip_aperture *perfmon); + +int th500_hwpm_soc_disable_mem_mgmt(struct tegra_soc_hwpm *hwpm); +int th500_hwpm_soc_enable_mem_mgmt(struct tegra_soc_hwpm *hwpm); +int th500_hwpm_soc_invalidate_mem_config(struct tegra_soc_hwpm *hwpm); +int th500_hwpm_soc_stream_mem_bytes(struct tegra_soc_hwpm *hwpm); +int th500_hwpm_soc_disable_pma_streaming(struct tegra_soc_hwpm *hwpm); +int th500_hwpm_soc_update_mem_bytes_get_ptr(struct tegra_soc_hwpm *hwpm, + u64 mem_bump); +u64 th500_hwpm_soc_get_mem_bytes_put_ptr(struct tegra_soc_hwpm *hwpm); +bool th500_hwpm_soc_membuf_overflow_status(struct tegra_soc_hwpm *hwpm); + +#endif /* TH500_HWPM_SOC_INTERNAL_H */ diff --git a/drivers/tegra/hwpm/hal/th500/soc/th500_soc_mem_mgmt.c b/drivers/tegra/hwpm/hal/th500/soc/th500_soc_mem_mgmt.c new file mode 100644 index 0000000..510cd2d --- /dev/null +++ b/drivers/tegra/hwpm/hal/th500/soc/th500_soc_mem_mgmt.c @@ -0,0 +1,338 @@ +// SPDX-License-Identifier: MIT +/* SPDX-FileCopyrightText: Copyright (c) 2022-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. + */ + +#include +#include +#include +#include +#include +#include + +#include + +int th500_hwpm_soc_disable_mem_mgmt(struct tegra_soc_hwpm *hwpm) +{ + int err = 0; + struct tegra_soc_hwpm_chip *active_chip = hwpm->active_chip; + struct hwpm_ip *chip_ip = active_chip->chip_ips[ + active_chip->get_rtr_int_idx(hwpm)]; + struct hwpm_ip_inst *ip_inst_pma = &chip_ip->ip_inst_static_array[ + TH500_HWPM_IP_RTR_STATIC_PMA_INST]; + struct hwpm_ip_aperture *pma_perfmux = &ip_inst_pma->element_info[ + TEGRA_HWPM_APERTURE_TYPE_PERFMUX].element_static_array[ + TH500_HWPM_IP_RTR_PERFMUX_INDEX]; + + tegra_hwpm_fn(hwpm, " "); + + err = tegra_hwpm_writel(hwpm, pma_perfmux, + pmasys_channel_outbase_r(0), 0); + if (err != 0) { + tegra_hwpm_err(hwpm, "hwpm write failed"); + return err; + } + err = tegra_hwpm_writel(hwpm, pma_perfmux, + pmasys_channel_outbaseupper_r(0), 0); + if (err != 0) { + tegra_hwpm_err(hwpm, "hwpm write failed"); + return err; + } + err = tegra_hwpm_writel(hwpm, pma_perfmux, + pmasys_channel_outsize_r(0), 0); + if (err != 0) { + tegra_hwpm_err(hwpm, "hwpm write failed"); + return err; + } + err = tegra_hwpm_writel(hwpm, pma_perfmux, + pmasys_channel_mem_bytes_addr_r(0), 0); + if (err != 0) { + tegra_hwpm_err(hwpm, "hwpm write failed"); + return err; + } + + return 0; +} + +int th500_hwpm_soc_enable_mem_mgmt(struct tegra_soc_hwpm *hwpm) +{ + int err = 0; + u32 outbase_lo = 0; + u32 outbase_hi = 0; + u32 outsize = 0; + u32 mem_bytes_addr = 0; + struct tegra_soc_hwpm_chip *active_chip = hwpm->active_chip; + struct hwpm_ip *chip_ip = active_chip->chip_ips[ + active_chip->get_rtr_int_idx(hwpm)]; + struct hwpm_ip_inst *ip_inst_pma = &chip_ip->ip_inst_static_array[ + TH500_HWPM_IP_RTR_STATIC_PMA_INST]; + struct hwpm_ip_aperture *pma_perfmux = &ip_inst_pma->element_info[ + TEGRA_HWPM_APERTURE_TYPE_PERFMUX].element_static_array[ + TH500_HWPM_IP_RTR_PERFMUX_INDEX]; + struct tegra_hwpm_mem_mgmt *mem_mgmt = hwpm->mem_mgmt; + + tegra_hwpm_fn(hwpm, " "); + + outbase_lo = mem_mgmt->stream_buf_va & pmasys_channel_outbase_ptr_m(); + err = tegra_hwpm_writel(hwpm, pma_perfmux, + pmasys_channel_outbase_r(0), outbase_lo); + if (err != 0) { + tegra_hwpm_err(hwpm, "hwpm write failed"); + return err; + } + tegra_hwpm_dbg(hwpm, hwpm_verbose, "OUTBASE = 0x%x", outbase_lo); + + outbase_hi = (mem_mgmt->stream_buf_va >> 32) & + pmasys_channel_outbaseupper_ptr_m(); + err = tegra_hwpm_writel(hwpm, pma_perfmux, + pmasys_channel_outbaseupper_r(0), outbase_hi); + if (err != 0) { + tegra_hwpm_err(hwpm, "hwpm write failed"); + return err; + } + tegra_hwpm_dbg(hwpm, hwpm_verbose, "OUTBASEUPPER = 0x%x", outbase_hi); + + outsize = mem_mgmt->stream_buf_size & + pmasys_channel_outsize_numbytes_m(); + err = tegra_hwpm_writel(hwpm, pma_perfmux, + pmasys_channel_outsize_r(0), outsize); + if (err != 0) { + tegra_hwpm_err(hwpm, "hwpm write failed"); + return err; + } + tegra_hwpm_dbg(hwpm, hwpm_verbose, "OUTSIZE = 0x%x", outsize); + + mem_bytes_addr = mem_mgmt->mem_bytes_buf_va & + pmasys_channel_mem_bytes_addr_ptr_m(); + err = tegra_hwpm_writel(hwpm, pma_perfmux, + pmasys_channel_mem_bytes_addr_r(0), mem_bytes_addr); + if (err != 0) { + tegra_hwpm_err(hwpm, "hwpm write failed"); + return err; + } + tegra_hwpm_dbg(hwpm, hwpm_verbose, + "MEM_BYTES_ADDR = 0x%x", mem_bytes_addr); + err = tegra_hwpm_writel(hwpm, pma_perfmux, + pmasys_channel_mem_block_r(0), + pmasys_channel_mem_blockupper_valid_f( + pmasys_channel_mem_blockupper_valid_true_v())); + if (err != 0) { + tegra_hwpm_err(hwpm, "hwpm write failed"); + return err; + } + + return 0; +} + +int th500_hwpm_soc_invalidate_mem_config(struct tegra_soc_hwpm *hwpm) +{ + int err = 0; + struct tegra_soc_hwpm_chip *active_chip = hwpm->active_chip; + struct hwpm_ip *chip_ip = active_chip->chip_ips[ + active_chip->get_rtr_int_idx(hwpm)]; + struct hwpm_ip_inst *ip_inst_pma = &chip_ip->ip_inst_static_array[ + TH500_HWPM_IP_RTR_STATIC_PMA_INST]; + struct hwpm_ip_aperture *pma_perfmux = &ip_inst_pma->element_info[ + TEGRA_HWPM_APERTURE_TYPE_PERFMUX].element_static_array[ + TH500_HWPM_IP_RTR_PERFMUX_INDEX]; + + tegra_hwpm_fn(hwpm, " "); + err = tegra_hwpm_writel(hwpm, pma_perfmux, pmasys_channel_mem_block_r(0), + pmasys_channel_mem_blockupper_valid_f( + pmasys_channel_mem_blockupper_valid_false_v())); + if (err != 0) { + tegra_hwpm_err(hwpm, "hwpm write failed"); + return err; + } + + return 0; +} + +int th500_hwpm_soc_stream_mem_bytes(struct tegra_soc_hwpm *hwpm) +{ + int err = 0; + u32 reg_val = 0U; + u32 *mem_bytes_kernel_u32 = + (u32 *)(hwpm->mem_mgmt->mem_bytes_kernel); + struct tegra_soc_hwpm_chip *active_chip = hwpm->active_chip; + struct hwpm_ip *chip_ip = active_chip->chip_ips[ + active_chip->get_rtr_int_idx(hwpm)]; + struct hwpm_ip_inst *ip_inst_pma = &chip_ip->ip_inst_static_array[ + TH500_HWPM_IP_RTR_STATIC_PMA_INST]; + struct hwpm_ip_aperture *pma_perfmux = &ip_inst_pma->element_info[ + TEGRA_HWPM_APERTURE_TYPE_PERFMUX].element_static_array[ + TH500_HWPM_IP_RTR_PERFMUX_INDEX]; + + tegra_hwpm_fn(hwpm, " "); + + *mem_bytes_kernel_u32 = TEGRA_HWPM_MEM_BYTES_INVALID; + + err = tegra_hwpm_readl(hwpm, pma_perfmux, + pmasys_channel_control_user_r(0), ®_val); + if (err != 0) { + tegra_hwpm_err(hwpm, "hwpm read failed"); + return err; + } + reg_val = set_field(reg_val, + pmasys_channel_control_user_update_bytes_m(), + pmasys_channel_control_user_update_bytes_doit_f()); + err = tegra_hwpm_writel(hwpm, pma_perfmux, + pmasys_channel_control_user_r(0), reg_val); + if (err != 0) { + tegra_hwpm_err(hwpm, "hwpm write failed"); + return err; + } + + return 0; +} + +int th500_hwpm_soc_disable_pma_streaming(struct tegra_soc_hwpm *hwpm) +{ + int err = 0; + u32 reg_val = 0U; + struct tegra_soc_hwpm_chip *active_chip = hwpm->active_chip; + struct hwpm_ip *chip_ip = active_chip->chip_ips[ + active_chip->get_rtr_int_idx(hwpm)]; + struct hwpm_ip_inst *ip_inst_pma = &chip_ip->ip_inst_static_array[ + TH500_HWPM_IP_RTR_STATIC_PMA_INST]; + struct hwpm_ip_aperture *pma_perfmux = &ip_inst_pma->element_info[ + TEGRA_HWPM_APERTURE_TYPE_PERFMUX].element_static_array[ + TH500_HWPM_IP_RTR_PERFMUX_INDEX]; + + tegra_hwpm_fn(hwpm, " "); + + /* Disable PMA streaming */ + err = tegra_hwpm_readl(hwpm, pma_perfmux, + pmasys_command_slice_trigger_config_user_r(0), ®_val); + if (err != 0) { + tegra_hwpm_err(hwpm, "hwpm read failed"); + return err; + } + reg_val = set_field(reg_val, + pmasys_command_slice_trigger_config_user_record_stream_m(), + pmasys_command_slice_trigger_config_user_record_stream_disable_f()); + err = tegra_hwpm_writel(hwpm, pma_perfmux, + pmasys_command_slice_trigger_config_user_r(0), reg_val); + if (err != 0) { + tegra_hwpm_err(hwpm, "hwpm write failed"); + return err; + } + + err = tegra_hwpm_readl(hwpm, pma_perfmux, + pmasys_channel_control_user_r(0), ®_val); + if (err != 0) { + tegra_hwpm_err(hwpm, "hwpm read failed"); + return err; + } + reg_val = set_field(reg_val, + pmasys_channel_config_user_stream_m(), + pmasys_channel_config_user_stream_disable_f()); + err = tegra_hwpm_writel(hwpm, pma_perfmux, + pmasys_channel_control_user_r(0), reg_val); + if (err != 0) { + tegra_hwpm_err(hwpm, "hwpm write failed"); + return err; + } + + return 0; +} + +int th500_hwpm_soc_update_mem_bytes_get_ptr(struct tegra_soc_hwpm *hwpm, + u64 mem_bump) +{ + int err = 0; + struct tegra_soc_hwpm_chip *active_chip = hwpm->active_chip; + struct hwpm_ip *chip_ip = active_chip->chip_ips[ + active_chip->get_rtr_int_idx(hwpm)]; + struct hwpm_ip_inst *ip_inst_pma = &chip_ip->ip_inst_static_array[ + TH500_HWPM_IP_RTR_STATIC_PMA_INST]; + struct hwpm_ip_aperture *pma_perfmux = &ip_inst_pma->element_info[ + TEGRA_HWPM_APERTURE_TYPE_PERFMUX].element_static_array[ + TH500_HWPM_IP_RTR_PERFMUX_INDEX]; + + tegra_hwpm_fn(hwpm, " "); + + if (mem_bump > (u64)U32_MAX) { + tegra_hwpm_err(hwpm, "mem_bump is out of bounds"); + return -EINVAL; + } + + err = tegra_hwpm_writel(hwpm, pma_perfmux, + pmasys_channel_mem_bump_r(0), mem_bump); + if (err != 0) { + tegra_hwpm_err(hwpm, "hwpm write failed"); + return err; + } + + return 0; +} + +u64 th500_hwpm_soc_get_mem_bytes_put_ptr(struct tegra_soc_hwpm *hwpm) +{ + int err = 0; + u32 reg_val = 0U; + struct tegra_soc_hwpm_chip *active_chip = hwpm->active_chip; + struct hwpm_ip *chip_ip = active_chip->chip_ips[ + active_chip->get_rtr_int_idx(hwpm)]; + struct hwpm_ip_inst *ip_inst_pma = &chip_ip->ip_inst_static_array[ + TH500_HWPM_IP_RTR_STATIC_PMA_INST]; + struct hwpm_ip_aperture *pma_perfmux = &ip_inst_pma->element_info[ + TEGRA_HWPM_APERTURE_TYPE_PERFMUX].element_static_array[ + TH500_HWPM_IP_RTR_PERFMUX_INDEX]; + + tegra_hwpm_fn(hwpm, " "); + + err = tegra_hwpm_readl(hwpm, pma_perfmux, + pmasys_channel_mem_head_r(0), ®_val); + if (err != 0) { + tegra_hwpm_err(hwpm, "hwpm read failed"); + return 0ULL; + } + + return (u64)reg_val; +} + +bool th500_hwpm_soc_membuf_overflow_status(struct tegra_soc_hwpm *hwpm) +{ + int err = 0; + u32 reg_val, field_val; + struct tegra_soc_hwpm_chip *active_chip = hwpm->active_chip; + struct hwpm_ip *chip_ip = active_chip->chip_ips[ + active_chip->get_rtr_int_idx(hwpm)]; + struct hwpm_ip_inst *ip_inst_pma = &chip_ip->ip_inst_static_array[ + TH500_HWPM_IP_RTR_STATIC_PMA_INST]; + struct hwpm_ip_aperture *pma_perfmux = &ip_inst_pma->element_info[ + TEGRA_HWPM_APERTURE_TYPE_PERFMUX].element_static_array[ + TH500_HWPM_IP_RTR_PERFMUX_INDEX]; + + tegra_hwpm_fn(hwpm, " "); + + err = tegra_hwpm_readl(hwpm, pma_perfmux, + pmasys_channel_status_r(0), ®_val); + if (err != 0) { + tegra_hwpm_err(hwpm, "hwpm read failed"); + return err; + } + field_val = pmasys_channel_status_membuf_status_v( + reg_val); + + return (field_val == + pmasys_channel_status_membuf_status_overflowed_v()); +} diff --git a/drivers/tegra/hwpm/hal/th500/soc/th500_soc_perfmon_device_index.h b/drivers/tegra/hwpm/hal/th500/soc/th500_soc_perfmon_device_index.h new file mode 100644 index 0000000..f539106 --- /dev/null +++ b/drivers/tegra/hwpm/hal/th500/soc/th500_soc_perfmon_device_index.h @@ -0,0 +1,172 @@ +/* SPDX-License-Identifier: MIT */ +/* SPDX-FileCopyrightText: Copyright (c) 2022-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. + */ + +#ifndef TH500_HWPM_SOC_PERFMON_DEVICE_INDEX_H +#define TH500_HWPM_SOC_PERFMON_DEVICE_INDEX_H + +enum th500_hwpm_soc_perfmon_device_index { + TH500_XALRC0_PERFMON_DEVICE_NODE_INDEX, + TH500_XALRC1_PERFMON_DEVICE_NODE_INDEX, + TH500_XALRC2_PERFMON_DEVICE_NODE_INDEX, + TH500_XALRC3_PERFMON_DEVICE_NODE_INDEX, + TH500_XALRC4_PERFMON_DEVICE_NODE_INDEX, + TH500_XALRC5_PERFMON_DEVICE_NODE_INDEX, + TH500_XALRC6_PERFMON_DEVICE_NODE_INDEX, + TH500_XALRC7_PERFMON_DEVICE_NODE_INDEX, + TH500_XALRC8_PERFMON_DEVICE_NODE_INDEX, + TH500_XALRC9_PERFMON_DEVICE_NODE_INDEX, + TH500_XTLRC0_PERFMON_DEVICE_NODE_INDEX, + TH500_XTLRC1_PERFMON_DEVICE_NODE_INDEX, + TH500_XTLRC2_PERFMON_DEVICE_NODE_INDEX, + TH500_XTLRC3_PERFMON_DEVICE_NODE_INDEX, + TH500_XTLRC4_PERFMON_DEVICE_NODE_INDEX, + TH500_XTLRC5_PERFMON_DEVICE_NODE_INDEX, + TH500_XTLRC6_PERFMON_DEVICE_NODE_INDEX, + TH500_XTLRC7_PERFMON_DEVICE_NODE_INDEX, + TH500_XTLRC8_PERFMON_DEVICE_NODE_INDEX, + TH500_XTLRC9_PERFMON_DEVICE_NODE_INDEX, + TH500_XTLQ0_PERFMON_DEVICE_NODE_INDEX, + TH500_XTLQ1_PERFMON_DEVICE_NODE_INDEX, + TH500_XTLQ2_PERFMON_DEVICE_NODE_INDEX, + TH500_XTLQ3_PERFMON_DEVICE_NODE_INDEX, + TH500_XTLQ4_PERFMON_DEVICE_NODE_INDEX, + TH500_XTLQ5_PERFMON_DEVICE_NODE_INDEX, + TH500_XTLQ6_PERFMON_DEVICE_NODE_INDEX, + TH500_XTLQ7_PERFMON_DEVICE_NODE_INDEX, + TH500_XTLQ8_PERFMON_DEVICE_NODE_INDEX, + TH500_XTLQ9_PERFMON_DEVICE_NODE_INDEX, + TH500_SYS0_PERFMON_DEVICE_NODE_INDEX, + TH500_MSS_CHANNEL_PARTA0_PERFMON_DEVICE_NODE_INDEX, + TH500_MSS_CHANNEL_PARTA1_PERFMON_DEVICE_NODE_INDEX, + TH500_MSS_CHANNEL_PARTA2_PERFMON_DEVICE_NODE_INDEX, + TH500_MSS_CHANNEL_PARTA3_PERFMON_DEVICE_NODE_INDEX, + TH500_MSS_CHANNEL_PARTB0_PERFMON_DEVICE_NODE_INDEX, + TH500_MSS_CHANNEL_PARTB1_PERFMON_DEVICE_NODE_INDEX, + TH500_MSS_CHANNEL_PARTB2_PERFMON_DEVICE_NODE_INDEX, + TH500_MSS_CHANNEL_PARTB3_PERFMON_DEVICE_NODE_INDEX, + TH500_MSS_CHANNEL_PARTC0_PERFMON_DEVICE_NODE_INDEX, + TH500_MSS_CHANNEL_PARTC1_PERFMON_DEVICE_NODE_INDEX, + TH500_MSS_CHANNEL_PARTC2_PERFMON_DEVICE_NODE_INDEX, + TH500_MSS_CHANNEL_PARTC3_PERFMON_DEVICE_NODE_INDEX, + TH500_MSS_CHANNEL_PARTD0_PERFMON_DEVICE_NODE_INDEX, + TH500_MSS_CHANNEL_PARTD1_PERFMON_DEVICE_NODE_INDEX, + TH500_MSS_CHANNEL_PARTD2_PERFMON_DEVICE_NODE_INDEX, + TH500_MSS_CHANNEL_PARTD3_PERFMON_DEVICE_NODE_INDEX, + TH500_MSS_CHANNEL_PARTE0_PERFMON_DEVICE_NODE_INDEX, + TH500_MSS_CHANNEL_PARTE1_PERFMON_DEVICE_NODE_INDEX, + TH500_MSS_CHANNEL_PARTE2_PERFMON_DEVICE_NODE_INDEX, + TH500_MSS_CHANNEL_PARTE3_PERFMON_DEVICE_NODE_INDEX, + TH500_MSS_CHANNEL_PARTF0_PERFMON_DEVICE_NODE_INDEX, + TH500_MSS_CHANNEL_PARTF1_PERFMON_DEVICE_NODE_INDEX, + TH500_MSS_CHANNEL_PARTF2_PERFMON_DEVICE_NODE_INDEX, + TH500_MSS_CHANNEL_PARTF3_PERFMON_DEVICE_NODE_INDEX, + TH500_MSS_CHANNEL_PARTG0_PERFMON_DEVICE_NODE_INDEX, + TH500_MSS_CHANNEL_PARTG1_PERFMON_DEVICE_NODE_INDEX, + TH500_MSS_CHANNEL_PARTG2_PERFMON_DEVICE_NODE_INDEX, + TH500_MSS_CHANNEL_PARTG3_PERFMON_DEVICE_NODE_INDEX, + TH500_MSS_CHANNEL_PARTH0_PERFMON_DEVICE_NODE_INDEX, + TH500_MSS_CHANNEL_PARTH1_PERFMON_DEVICE_NODE_INDEX, + TH500_MSS_CHANNEL_PARTH2_PERFMON_DEVICE_NODE_INDEX, + TH500_MSS_CHANNEL_PARTH3_PERFMON_DEVICE_NODE_INDEX, + TH500_LTS0_PERFMON_DEVICE_NODE_INDEX, + TH500_LTS1_PERFMON_DEVICE_NODE_INDEX, + TH500_LTS2_PERFMON_DEVICE_NODE_INDEX, + TH500_LTS3_PERFMON_DEVICE_NODE_INDEX, + TH500_LTS4_PERFMON_DEVICE_NODE_INDEX, + TH500_LTS5_PERFMON_DEVICE_NODE_INDEX, + TH500_LTS6_PERFMON_DEVICE_NODE_INDEX, + TH500_LTS7_PERFMON_DEVICE_NODE_INDEX, + TH500_LTS8_PERFMON_DEVICE_NODE_INDEX, + TH500_LTS9_PERFMON_DEVICE_NODE_INDEX, + TH500_LTS10_PERFMON_DEVICE_NODE_INDEX, + TH500_LTS11_PERFMON_DEVICE_NODE_INDEX, + TH500_LTS12_PERFMON_DEVICE_NODE_INDEX, + TH500_LTS13_PERFMON_DEVICE_NODE_INDEX, + TH500_LTS14_PERFMON_DEVICE_NODE_INDEX, + TH500_LTS15_PERFMON_DEVICE_NODE_INDEX, + TH500_MCFCORE0_PERFMON_DEVICE_NODE_INDEX, + TH500_MCFCORE1_PERFMON_DEVICE_NODE_INDEX, + TH500_MCFCORE2_PERFMON_DEVICE_NODE_INDEX, + TH500_MCFCORE3_PERFMON_DEVICE_NODE_INDEX, + TH500_MCFCORE4_PERFMON_DEVICE_NODE_INDEX, + TH500_MCFCORE5_PERFMON_DEVICE_NODE_INDEX, + TH500_MCFCORE6_PERFMON_DEVICE_NODE_INDEX, + TH500_MCFCORE7_PERFMON_DEVICE_NODE_INDEX, + TH500_MCFCORE8_PERFMON_DEVICE_NODE_INDEX, + TH500_MCFCORE9_PERFMON_DEVICE_NODE_INDEX, + TH500_MCFCORE10_PERFMON_DEVICE_NODE_INDEX, + TH500_MCFCORE11_PERFMON_DEVICE_NODE_INDEX, + TH500_MCFCORE12_PERFMON_DEVICE_NODE_INDEX, + TH500_MCFCORE13_PERFMON_DEVICE_NODE_INDEX, + TH500_MCFCORE14_PERFMON_DEVICE_NODE_INDEX, + TH500_MCFCORE15_PERFMON_DEVICE_NODE_INDEX, + TH500_MCFSYS0_PERFMON_DEVICE_NODE_INDEX, + TH500_MCFSYS1_PERFMON_DEVICE_NODE_INDEX, + TH500_MCFCTC0_PERFMON_DEVICE_NODE_INDEX, + TH500_MCFCTC1_PERFMON_DEVICE_NODE_INDEX, + TH500_MCFSOC0_PERFMON_DEVICE_NODE_INDEX, + TH500_SMMU0_PERFMON_DEVICE_NODE_INDEX, + TH500_SMMU1_PERFMON_DEVICE_NODE_INDEX, + TH500_SMMU2_PERFMON_DEVICE_NODE_INDEX, + TH500_SMMU3_PERFMON_DEVICE_NODE_INDEX, + TH500_SMMU4_PERFMON_DEVICE_NODE_INDEX, + TH500_MSSHUB0_PERFMON_DEVICE_NODE_INDEX, + TH500_MSSHUB1_PERFMON_DEVICE_NODE_INDEX, + TH500_MSSHUB2_PERFMON_DEVICE_NODE_INDEX, + TH500_MSSHUB3_PERFMON_DEVICE_NODE_INDEX, + TH500_MSSHUB4_PERFMON_DEVICE_NODE_INDEX, + TH500_MSSHUB5_PERFMON_DEVICE_NODE_INDEX, + TH500_MSSHUB6_PERFMON_DEVICE_NODE_INDEX, + TH500_MSSHUB7_PERFMON_DEVICE_NODE_INDEX, + TH500_NVLTX0_PERFMON_DEVICE_NODE_INDEX, + TH500_NVLTX1_PERFMON_DEVICE_NODE_INDEX, + TH500_NVLTX2_PERFMON_DEVICE_NODE_INDEX, + TH500_NVLTX3_PERFMON_DEVICE_NODE_INDEX, + TH500_NVLTX4_PERFMON_DEVICE_NODE_INDEX, + TH500_NVLTX5_PERFMON_DEVICE_NODE_INDEX, + TH500_NVLTX6_PERFMON_DEVICE_NODE_INDEX, + TH500_NVLTX7_PERFMON_DEVICE_NODE_INDEX, + TH500_NVLTX8_PERFMON_DEVICE_NODE_INDEX, + TH500_NVLTX9_PERFMON_DEVICE_NODE_INDEX, + TH500_NVLTX10_PERFMON_DEVICE_NODE_INDEX, + TH500_NVLTX11_PERFMON_DEVICE_NODE_INDEX, + TH500_NVLRX0_PERFMON_DEVICE_NODE_INDEX, + TH500_NVLRX1_PERFMON_DEVICE_NODE_INDEX, + TH500_NVLRX2_PERFMON_DEVICE_NODE_INDEX, + TH500_NVLRX3_PERFMON_DEVICE_NODE_INDEX, + TH500_NVLRX4_PERFMON_DEVICE_NODE_INDEX, + TH500_NVLRX5_PERFMON_DEVICE_NODE_INDEX, + TH500_NVLRX6_PERFMON_DEVICE_NODE_INDEX, + TH500_NVLRX7_PERFMON_DEVICE_NODE_INDEX, + TH500_NVLRX8_PERFMON_DEVICE_NODE_INDEX, + TH500_NVLRX9_PERFMON_DEVICE_NODE_INDEX, + TH500_NVLRX10_PERFMON_DEVICE_NODE_INDEX, + TH500_NVLRX11_PERFMON_DEVICE_NODE_INDEX, + TH500_CTRL0_PERFMON_DEVICE_NODE_INDEX, + TH500_CTRL1_PERFMON_DEVICE_NODE_INDEX, + TH500_CTC0_PERFMON_DEVICE_NODE_INDEX, + TH500_CTC1_PERFMON_DEVICE_NODE_INDEX, + TH500_PMA_DEVICE_NODE_INDEX, + TH500_RTR_DEVICE_NODE_INDEX, +}; + +#endif 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 new file mode 100644 index 0000000..ebd196a --- /dev/null +++ b/drivers/tegra/hwpm/hal/th500/soc/th500_soc_regops_allowlist.c @@ -0,0 +1,246 @@ +/* + * Copyright (c) 2022-2023, NVIDIA CORPORATION. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + * + * This file is autogenerated. Do not edit. + */ + +#include "th500_soc_regops_allowlist.h" + +struct allowlist th500_perfmon_alist[67] = { + {0x00000000, true}, + {0x00000004, true}, + {0x00000008, true}, + {0x0000000c, true}, + {0x00000010, true}, + {0x00000014, true}, + {0x00000020, true}, + {0x00000024, true}, + {0x00000028, true}, + {0x0000002c, true}, + {0x00000030, true}, + {0x00000034, true}, + {0x00000040, true}, + {0x00000044, true}, + {0x00000048, true}, + {0x0000004c, true}, + {0x00000050, true}, + {0x00000054, true}, + {0x00000058, true}, + {0x0000005c, true}, + {0x00000060, true}, + {0x00000064, true}, + {0x00000068, true}, + {0x0000006c, true}, + {0x00000070, true}, + {0x00000074, true}, + {0x00000078, true}, + {0x0000007c, true}, + {0x00000080, true}, + {0x00000084, true}, + {0x00000088, true}, + {0x0000008c, true}, + {0x00000090, true}, + {0x00000098, true}, + {0x0000009c, true}, + {0x000000a0, true}, + {0x000000a4, true}, + {0x000000a8, true}, + {0x000000ac, true}, + {0x000000b0, true}, + {0x000000b4, true}, + {0x000000b8, true}, + {0x000000bc, true}, + {0x000000c0, true}, + {0x000000c4, true}, + {0x000000c8, true}, + {0x000000cc, true}, + {0x000000d0, true}, + {0x000000d4, true}, + {0x000000d8, true}, + {0x000000dc, true}, + {0x000000e0, true}, + {0x000000e4, true}, + {0x000000e8, true}, + {0x000000ec, true}, + {0x000000f8, true}, + {0x000000fc, true}, + {0x00000100, true}, + {0x00000108, true}, + {0x00000110, true}, + {0x00000114, true}, + {0x00000118, true}, + {0x0000011c, true}, + {0x00000120, true}, + {0x00000124, true}, + {0x00000128, true}, + {0x00000130, true}, +}; + +struct allowlist th500_pma_res_cmd_slice_rtr_alist[44] = { + {0x00000800, false}, + {0x00000a00, false}, + {0x00000a10, false}, + {0x00000a20, false}, + {0x00000a24, false}, + {0x00000a38, false}, + {0x00000a3c, false}, + {0x00000a40, false}, + {0x00000a44, false}, + {0x00000a48, false}, + {0x00000a4c, false}, + {0x00000a50, false}, + {0x00000a54, false}, + {0x00000a58, false}, + {0x00000a5c, false}, + {0x00000ae4, false}, + {0x00000af0, false}, + {0x00000af4, false}, + {0x00000afc, false}, + {0x00000b00, false}, + {0x00000b04, false}, + {0x00000b08, false}, + {0x00000b0c, false}, + {0x00000b10, false}, + {0x00000b14, false}, + {0x00000b18, false}, + {0x00000b1c, false}, + {0x00000b20, false}, + {0x00000b24, false}, + {0x00000b28, false}, + {0x00000b2c, false}, + {0x00000b30, false}, + {0x00000b34, false}, + {0x00000b38, false}, + {0x00000b3c, false}, + {0x00000b40, false}, + {0x00000b44, false}, + {0x00000b48, false}, + {0x00000b4c, false}, + {0x00000b50, false}, + {0x00000b54, false}, + {0x00000b58, false}, + {0x00000b5c, false}, + {0x0000075c, false}, +}; + +struct allowlist th500_pma_res_pma_alist[1] = { + {0x00000800, true}, +}; + +struct allowlist th500_rtr_alist[5] = { + {0x0000005c, false}, + {0x00000044, false}, + {0x00000050, false}, + {0x00000048, false}, + {0x0000004c, false}, +}; + +struct allowlist th500_nvlink_alist[0] = { +}; + +struct allowlist th500_smmu_alist[1] = { + {0x00005000, false}, +}; + +struct allowlist th500_c2c_alist[52] = { + {0x00000028, false}, + {0x00001028, false}, + {0x000020ec, false}, + {0x000020f0, false}, + {0x000020f4, false}, + {0x000020f8, false}, + {0x000020fc, false}, + {0x000030ec, false}, + {0x000030f0, false}, + {0x000030f4, false}, + {0x000030f8, false}, + {0x000030fc, false}, + {0x000040ec, false}, + {0x000040f0, false}, + {0x000040f4, false}, + {0x000040f8, false}, + {0x000040fc, false}, + {0x000050ec, false}, + {0x000050f0, false}, + {0x000050f4, false}, + {0x000050f8, false}, + {0x000050fc, false}, + {0x000060ec, false}, + {0x000060f0, false}, + {0x000060f4, false}, + {0x000060f8, false}, + {0x000060fc, false}, + {0x000070ec, false}, + {0x000070f0, false}, + {0x000070f4, false}, + {0x000070f8, false}, + {0x000070fc, false}, + {0x000080ec, false}, + {0x000080f0, false}, + {0x000080f4, false}, + {0x000080f8, false}, + {0x000080fc, false}, + {0x000090ec, false}, + {0x000090f0, false}, + {0x000090f4, false}, + {0x000090f8, false}, + {0x000090fc, false}, + {0x0000a0ec, false}, + {0x0000a0f0, false}, + {0x0000a0f4, false}, + {0x0000a0f8, false}, + {0x0000a0fc, false}, + {0x0000b0ec, false}, + {0x0000b0f0, false}, + {0x0000b0f4, false}, + {0x0000b0f8, false}, + {0x0000b0fc, false}, +}; + +struct allowlist th500_pcie_alist[1] = { + {0x00000470, true}, +}; + +struct allowlist th500_mss_channel_alist[2] = { + {0x00008914, false}, + {0x00008918, false}, +}; + +struct allowlist th500_mcf_core_alist[2] = { + {0x0000d604, false}, + {0x0000d600, false}, +}; + +struct allowlist th500_mcf_clink_alist[3] = { + {0x0000d610, false}, + {0x0000d614, false}, + {0x0000e430, false}, +}; + +struct allowlist th500_mcf_c2c_alist[2] = { + {0x0000d608, false}, + {0x0000d60c, false}, +}; + +struct allowlist th500_mcf_soc_alist[2] = { + {0x0000d618, false}, + {0x0000d61c, false}, +}; + +struct allowlist th500_soc_hub_alist[3] = { + {0x00006f34, false}, + {0x00006f38, false}, + {0x00006f3c, 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 new file mode 100644 index 0000000..608cad2 --- /dev/null +++ b/drivers/tegra/hwpm/hal/th500/soc/th500_soc_regops_allowlist.h @@ -0,0 +1,39 @@ +/* + * Copyright (c) 2022-2023, NVIDIA CORPORATION. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + * + * This file is autogenerated. Do not edit. + */ + +#ifndef TH500_HWPM_REGOPS_ALLOWLIST_H +#define TH500_HWPM_REGOPS_ALLOWLIST_H + +#include + +extern struct allowlist th500_perfmon_alist[67]; +extern struct allowlist th500_pma_res_cmd_slice_rtr_alist[44]; +extern struct allowlist th500_pma_res_pma_alist[1]; +extern struct allowlist th500_rtr_alist[5]; +extern struct allowlist th500_nvlink_alist[0]; +extern struct allowlist th500_smmu_alist[1]; +extern struct allowlist th500_c2c_alist[52]; +extern struct allowlist th500_pcie_alist[1]; +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_soc_hub_alist[3]; + +#endif /* TH500_HWPM_REGOPS_ALLOWLIST_H */ diff --git a/drivers/tegra/hwpm/hal/th500/soc/th500_soc_resource.c b/drivers/tegra/hwpm/hal/th500/soc/th500_soc_resource.c new file mode 100644 index 0000000..14f960f --- /dev/null +++ b/drivers/tegra/hwpm/hal/th500/soc/th500_soc_resource.c @@ -0,0 +1,98 @@ +// SPDX-License-Identifier: MIT +/* SPDX-FileCopyrightText: Copyright (c) 2022-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. + */ + +#include +#include +#include + +#include + +#include +#include + +int th500_hwpm_soc_perfmon_enable(struct tegra_soc_hwpm *hwpm, + struct hwpm_ip_aperture *perfmon) +{ + int err = 0; + u32 reg_val; + + tegra_hwpm_fn(hwpm, " "); + + /* Enable */ + tegra_hwpm_dbg(hwpm, hwpm_dbg_bind, + "Enabling PERFMON(0x%llx - 0x%llx)", + perfmon->start_abs_pa, perfmon->end_abs_pa); + + err = tegra_hwpm_readl(hwpm, perfmon, + pmmsys_sys0_enginestatus_r(0), ®_val); + if (err != 0) { + tegra_hwpm_err(hwpm, "hwpm read failed"); + return err; + } + reg_val = set_field(reg_val, pmmsys_sys0_enginestatus_enable_m(), + pmmsys_sys0_enginestatus_enable_out_f()); + err = tegra_hwpm_writel(hwpm, perfmon, + pmmsys_sys0_enginestatus_r(0), reg_val); + if (err != 0) { + tegra_hwpm_err(hwpm, "hwpm write failed"); + return err; + } + + return 0; +} + +int th500_hwpm_soc_perfmon_disable(struct tegra_soc_hwpm *hwpm, + struct hwpm_ip_aperture *perfmon) +{ + int err = 0; + u32 reg_val; + + tegra_hwpm_fn(hwpm, " "); + + if (perfmon->element_type == HWPM_ELEMENT_PERFMUX) { + /* + * Since HWPM elements use perfmon functions, + * skip disabling HWPM PERFMUX elements + */ + return 0; + } + + /* Disable */ + tegra_hwpm_dbg(hwpm, hwpm_dbg_release_resource, + "Disabling PERFMON(0x%llx - 0x%llx)", + perfmon->start_abs_pa, perfmon->end_abs_pa); + + err = tegra_hwpm_readl(hwpm, perfmon, pmmsys_control_r(0), ®_val); + if (err != 0) { + tegra_hwpm_err(hwpm, "hwpm read failed"); + return err; + } + reg_val = set_field(reg_val, pmmsys_control_mode_m(), + pmmsys_control_mode_disable_f()); + err = tegra_hwpm_writel(hwpm, perfmon, pmmsys_control_r(0), reg_val); + if (err != 0) { + tegra_hwpm_err(hwpm, "hwpm write failed"); + return err; + } + + return 0; +} diff --git a/drivers/tegra/hwpm/hal/th500/th500_init.h b/drivers/tegra/hwpm/hal/th500/th500_init.h new file mode 100644 index 0000000..b79994f --- /dev/null +++ b/drivers/tegra/hwpm/hal/th500/th500_init.h @@ -0,0 +1,30 @@ +/* SPDX-License-Identifier: MIT */ +/* Copyright (c) 2022-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. + */ + +#ifndef TH500_HWPM_INIT_H +#define TH500_HWPM_INIT_H + +struct tegra_soc_hwpm; + +int th500_hwpm_init_chip_info(struct tegra_soc_hwpm *hwpm); + +#endif /* TH500_HWPM_INIT_H */ diff --git a/drivers/tegra/hwpm/hal/th500/th500_interface.c b/drivers/tegra/hwpm/hal/th500/th500_interface.c new file mode 100644 index 0000000..5a785ef --- /dev/null +++ b/drivers/tegra/hwpm/hal/th500/th500_interface.c @@ -0,0 +1,330 @@ +// SPDX-License-Identifier: MIT +/* + * Copyright (c) 2022-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. + */ + +#include +#include +#include +#include +#include +#include +#include + +static struct tegra_soc_hwpm_chip th500_chip_info = { + .chip_ips = NULL, + + /* HALs */ + .validate_secondary_hals = th500_hwpm_validate_secondary_hals, + + /* Clocks and resets are configured by UEFI */ + .clk_rst_prepare = NULL, + .clk_rst_set_rate_enable = NULL, + .clk_rst_disable = NULL, + .clk_rst_release = NULL, + + .is_ip_active = th500_hwpm_is_ip_active, + .is_resource_active = th500_hwpm_is_resource_active, + + .get_rtr_int_idx = th500_get_rtr_int_idx, + .get_ip_max_idx = th500_get_ip_max_idx, + + .extract_ip_ops = th500_hwpm_extract_ip_ops, + .force_enable_ips = th500_hwpm_force_enable_ips, + .validate_current_config = th500_hwpm_validate_current_config, + .get_fs_info = tegra_hwpm_get_fs_info, + .get_resource_info = tegra_hwpm_get_resource_info, + + .init_prod_values = th500_hwpm_soc_init_prod_values, + .disable_cg = th500_hwpm_soc_disable_cg, + .enable_cg = th500_hwpm_soc_enable_cg, + + .reserve_rtr = tegra_hwpm_reserve_rtr, + .release_rtr = tegra_hwpm_release_rtr, + + .perfmon_enable = th500_hwpm_soc_perfmon_enable, + .perfmon_disable = th500_hwpm_soc_perfmon_disable, + .perfmux_disable = tegra_hwpm_perfmux_disable, + .disable_triggers = th500_hwpm_soc_disable_triggers, + .check_status = th500_hwpm_soc_check_status, + + .disable_mem_mgmt = th500_hwpm_soc_disable_mem_mgmt, + .enable_mem_mgmt = th500_hwpm_soc_enable_mem_mgmt, + .invalidate_mem_config = th500_hwpm_soc_invalidate_mem_config, + .stream_mem_bytes = th500_hwpm_soc_stream_mem_bytes, + .disable_pma_streaming = th500_hwpm_soc_disable_pma_streaming, + .update_mem_bytes_get_ptr = th500_hwpm_soc_update_mem_bytes_get_ptr, + .get_mem_bytes_put_ptr = th500_hwpm_soc_get_mem_bytes_put_ptr, + .membuf_overflow_status = th500_hwpm_soc_membuf_overflow_status, + + .get_alist_buf_size = tegra_hwpm_get_alist_buf_size, + .zero_alist_regs = tegra_hwpm_zero_alist_regs, + .copy_alist = tegra_hwpm_copy_alist, + .check_alist = tegra_hwpm_check_alist, +}; + +bool th500_hwpm_validate_secondary_hals(struct tegra_soc_hwpm *hwpm) +{ + /* + * Clocks and resets are configured by UEFI + * So clock-reset HALs are expected to be NULL + */ + if (hwpm->active_chip->clk_rst_prepare != NULL) { + tegra_hwpm_err(hwpm, "clk_rst_prepare HAL initialized"); + return false; + } + + if (hwpm->active_chip->clk_rst_set_rate_enable != NULL) { + tegra_hwpm_err(hwpm, + "clk_rst_set_rate_enable HAL initialized"); + return false; + } + + if (hwpm->active_chip->clk_rst_disable != NULL) { + tegra_hwpm_err(hwpm, "clk_rst_disable HAL initialized"); + return false; + } + + if (hwpm->active_chip->clk_rst_release != NULL) { + tegra_hwpm_err(hwpm, "clk_rst_release HAL initialized"); + return false; + } + + return true; +} + +bool th500_hwpm_is_ip_active(struct tegra_soc_hwpm *hwpm, + u32 ip_enum, u32 *config_ip_index) +{ + u32 config_ip = TEGRA_HWPM_IP_INACTIVE; + + switch (ip_enum) { +#if defined(CONFIG_TH500_HWPM_IP_MSS_CHANNEL) + case TEGRA_HWPM_IP_MSS_CHANNEL: + config_ip = TH500_HWPM_IP_MSS_CHANNEL; + break; +#endif +#if defined(CONFIG_TH500_HWPM_IP_CL2) + case TEGRA_HWPM_IP_CL2: + config_ip = TH500_HWPM_IP_CL2; + break; +#endif +#if defined(CONFIG_TH500_HWPM_IP_MCF_CORE) + case TEGRA_HWPM_IP_MCF_CORE: + config_ip = TH500_HWPM_IP_MCF_CORE; + break; +#endif +#if defined(CONFIG_TH500_HWPM_IP_MCF_CLINK) + case TEGRA_HWPM_IP_MCF_CLINK: + config_ip = TH500_HWPM_IP_MCF_CLINK; + break; +#endif +#if defined(CONFIG_TH500_HWPM_IP_MCF_C2C) + case TEGRA_HWPM_IP_MCF_C2C: + 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; + break; +#endif +#if defined(CONFIG_TH500_HWPM_IP_SMMU) + case TEGRA_HWPM_IP_SMMU: + config_ip = TH500_HWPM_IP_SMMU; + break; +#endif +#if defined(CONFIG_TH500_HWPM_IP_SOC_HUB) + case TEGRA_HWPM_IP_SOC_HUB: + config_ip = TH500_HWPM_IP_SOC_HUB; + break; +#endif +#if defined(CONFIG_TH500_HWPM_IP_C_NVLINK) + case TEGRA_HWPM_IP_C_NVLINK: + config_ip = TH500_HWPM_IP_C_NVLINK; + break; +#endif +#if defined(CONFIG_TH500_HWPM_IP_PCIE) + case TEGRA_HWPM_IP_PCIE: + config_ip = TH500_HWPM_IP_PCIE; + break; +#endif +#if defined(CONFIG_TH500_HWPM_IP_C2C) + case TEGRA_HWPM_IP_C2C: + config_ip = TH500_HWPM_IP_C2C; + break; +#endif + default: + tegra_hwpm_err(hwpm, + "Queried enum tegra_soc_hwpm_ip %d invalid", ip_enum); + break; + } + + *config_ip_index = config_ip; + return (config_ip != TEGRA_HWPM_IP_INACTIVE); +} + +bool th500_hwpm_is_resource_active(struct tegra_soc_hwpm *hwpm, + u32 res_index, u32 *config_ip_index) +{ + u32 config_ip = TEGRA_HWPM_IP_INACTIVE; + + switch (res_index) { +#if defined(CONFIG_TH500_HWPM_IP_MSS_CHANNEL) + case TEGRA_HWPM_RESOURCE_MSS_CHANNEL: + config_ip = TH500_HWPM_IP_MSS_CHANNEL; + break; +#endif +#if defined(CONFIG_TH500_HWPM_IP_CL2) + case TEGRA_HWPM_RESOURCE_CL2: + config_ip = TH500_HWPM_IP_CL2; + break; +#endif +#if defined(CONFIG_TH500_HWPM_IP_MCF_CORE) + case TEGRA_HWPM_RESOURCE_MCF_CORE: + config_ip = TH500_HWPM_IP_MCF_CORE; + break; +#endif +#if defined(CONFIG_TH500_HWPM_IP_MCF_CLINK) + case TEGRA_HWPM_RESOURCE_MCF_CLINK: + config_ip = TH500_HWPM_IP_MCF_CLINK; + break; +#endif +#if defined(CONFIG_TH500_HWPM_IP_MCF_C2C) + case TEGRA_HWPM_RESOURCE_MCF_C2C: + 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; + break; +#endif +#if defined(CONFIG_TH500_HWPM_IP_SMMU) + case TEGRA_HWPM_RESOURCE_SMMU: + config_ip = TH500_HWPM_IP_SMMU; + break; +#endif +#if defined(CONFIG_TH500_HWPM_IP_SOC_HUB) + case TEGRA_HWPM_RESOURCE_SOC_HUB: + config_ip = TH500_HWPM_IP_SOC_HUB; + break; +#endif +#if defined(CONFIG_TH500_HWPM_IP_C_NVLINK) + case TEGRA_HWPM_RESOURCE_C_NVLINK: + config_ip = TH500_HWPM_IP_C_NVLINK; + break; +#endif +#if defined(CONFIG_TH500_HWPM_IP_PCIE) + case TEGRA_HWPM_RESOURCE_PCIE: + config_ip = TH500_HWPM_IP_PCIE; + break; +#endif +#if defined(CONFIG_TH500_HWPM_IP_C2C) + case TEGRA_HWPM_RESOURCE_C2C: + config_ip = TH500_HWPM_IP_C2C; + break; +#endif + case TEGRA_HWPM_RESOURCE_PMA: + config_ip = TH500_HWPM_IP_PMA; + break; + case TEGRA_HWPM_RESOURCE_CMD_SLICE_RTR: + config_ip = TH500_HWPM_IP_RTR; + break; + default: + tegra_hwpm_err(hwpm, "Queried resource %d invalid", + res_index); + break; + } + + *config_ip_index = config_ip; + return (config_ip != TEGRA_HWPM_IP_INACTIVE); +} + +u32 th500_get_rtr_int_idx(struct tegra_soc_hwpm *hwpm) +{ + return TH500_HWPM_IP_RTR; +} + +u32 th500_get_ip_max_idx(struct tegra_soc_hwpm *hwpm) +{ + return TH500_HWPM_IP_MAX; +} + +int th500_hwpm_init_chip_info(struct tegra_soc_hwpm *hwpm) +{ + struct hwpm_ip **th500_active_ip_info; + + /* Allocate array of pointers to hold active IP structures */ + th500_chip_info.chip_ips = tegra_hwpm_kcalloc( + hwpm, TH500_HWPM_IP_MAX, sizeof(struct hwpm_ip *)); + + /* Add active chip structure link to hwpm super-structure */ + hwpm->active_chip = &th500_chip_info; + + /* Temporary pointer to make below assignments legible */ + th500_active_ip_info = th500_chip_info.chip_ips; + + th500_active_ip_info[TH500_HWPM_IP_PMA] = &th500_hwpm_ip_pma; + th500_active_ip_info[TH500_HWPM_IP_RTR] = &th500_hwpm_ip_rtr; + +#if defined(CONFIG_TH500_HWPM_IP_MSS_CHANNEL) + th500_active_ip_info[TH500_HWPM_IP_MSS_CHANNEL] = + &th500_hwpm_ip_mss_channel; +#endif +#if defined(CONFIG_TH500_HWPM_IP_CL2) + th500_active_ip_info[TH500_HWPM_IP_CL2] = &th500_hwpm_ip_cl2; +#endif +#if defined(CONFIG_TH500_HWPM_IP_MCF_CORE) + th500_active_ip_info[TH500_HWPM_IP_MCF_CORE] = &th500_hwpm_ip_mcf_core; +#endif +#if defined(CONFIG_TH500_HWPM_IP_MCF_CLINK) + th500_active_ip_info[TH500_HWPM_IP_MCF_CLINK] = + &th500_hwpm_ip_mcf_clink; +#endif +#if defined(CONFIG_TH500_HWPM_IP_MCF_C2C) + 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; +#endif +#if defined(CONFIG_TH500_HWPM_IP_SMMU) + th500_active_ip_info[TH500_HWPM_IP_SMMU] = &th500_hwpm_ip_smmu; +#endif +#if defined(CONFIG_TH500_HWPM_IP_C_NVLINK) + th500_active_ip_info[TH500_HWPM_IP_C_NVLINK] = &th500_hwpm_ip_c_nvlink; +#endif +#if defined(CONFIG_TH500_HWPM_IP_SOC_HUB) + th500_active_ip_info[TH500_HWPM_IP_SOC_HUB] = &th500_hwpm_ip_soc_hub; +#endif +#if defined(CONFIG_TH500_HWPM_IP_PCIE) + th500_active_ip_info[TH500_HWPM_IP_PCIE] = &th500_hwpm_ip_pcie; +#endif +#if defined(CONFIG_TH500_HWPM_IP_C2C) + th500_active_ip_info[TH500_HWPM_IP_C2C] = &th500_hwpm_ip_c2c; +#endif + if (!tegra_hwpm_validate_primary_hals(hwpm)) { + return -EINVAL; + } + return 0; +} diff --git a/drivers/tegra/hwpm/hal/th500/th500_internal.h b/drivers/tegra/hwpm/hal/th500/th500_internal.h new file mode 100644 index 0000000..a343fa2 --- /dev/null +++ b/drivers/tegra/hwpm/hal/th500/th500_internal.h @@ -0,0 +1,58 @@ +/* SPDX-License-Identifier: MIT */ +/* Copyright (c) 2022-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. + */ + +#ifndef TH500_HWPM_INTERNAL_H +#define TH500_HWPM_INTERNAL_H + +#include +#include +#include +#include + +#define TH500_HWPM_ACTIVE_IP_MAX TH500_HWPM_IP_MAX + +#define TH500_ACTIVE_IPS \ + DEFINE_SOC_HWPM_ACTIVE_IP(TH500_HWPM_ACTIVE_IP_RTR) \ + DEFINE_SOC_HWPM_ACTIVE_IP(TH500_HWPM_ACTIVE_IP_PMA) \ + DEFINE_SOC_HWPM_ACTIVE_IP(TH500_HWPM_ACTIVE_IP_MSS_CHANNEL) \ + DEFINE_SOC_HWPM_ACTIVE_IP(TH500_HWPM_ACTIVE_IP_C2C) \ + DEFINE_SOC_HWPM_ACTIVE_IP(TH500_HWPM_ACTIVE_IP_MAX) + +#undef DEFINE_SOC_HWPM_ACTIVE_IP +#define DEFINE_SOC_HWPM_ACTIVE_IP(name) name +enum th500_hwpm_active_ips { + TH500_ACTIVE_IPS +}; +#undef DEFINE_SOC_HWPM_ACTIVE_IP + +struct tegra_soc_hwpm; + +bool th500_hwpm_validate_secondary_hals(struct tegra_soc_hwpm *hwpm); +bool th500_hwpm_is_ip_active(struct tegra_soc_hwpm *hwpm, + u32 ip_index, u32 *config_ip_index); +bool th500_hwpm_is_resource_active(struct tegra_soc_hwpm *hwpm, + u32 res_index, u32 *config_ip_index); + +u32 th500_get_rtr_int_idx(struct tegra_soc_hwpm *hwpm); +u32 th500_get_ip_max_idx(struct tegra_soc_hwpm *hwpm); + +#endif /* TH500_HWPM_INTERNAL_H */ diff --git a/drivers/tegra/hwpm/hal/th500/th500_ip.c b/drivers/tegra/hwpm/hal/th500/th500_ip.c new file mode 100644 index 0000000..69052a5 --- /dev/null +++ b/drivers/tegra/hwpm/hal/th500/th500_ip.c @@ -0,0 +1,415 @@ +// SPDX-License-Identifier: MIT +/* Copyright (c) 2022-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. + */ + +#include +#include +#include +#include +#include +#include + +#include +#include +#include + +/* + * This function is invoked by register_ip API. + * Convert the external resource enum to internal IP index. + * Extract given ip_ops and update corresponding IP structure. + */ +int th500_hwpm_extract_ip_ops(struct tegra_soc_hwpm *hwpm, + u32 resource_enum, u64 base_address, + struct tegra_hwpm_ip_ops *ip_ops, bool available) +{ + int ret = 0; + u32 ip_idx = 0U; + + tegra_hwpm_fn(hwpm, " "); + + tegra_hwpm_dbg(hwpm, hwpm_dbg_ip_register, + "Extract IP ops for resource enum %d info", resource_enum); + + /* Convert tegra_soc_hwpm_resource to internal enum */ + if (!(hwpm->active_chip->is_resource_active(hwpm, + resource_enum, &ip_idx))) { + tegra_hwpm_dbg(hwpm, hwpm_dbg_ip_register, + "SOC hwpm resource %d (base 0x%llx) is unconfigured", + resource_enum, base_address); + goto fail; + } + + switch (ip_idx) { +#if defined(CONFIG_TH500_HWPM_IP_CL2) + case TH500_HWPM_IP_CL2: +#endif +#if defined(CONFIG_TH500_HWPM_IP_SMMU) + case TH500_HWPM_IP_SMMU: +#endif +#if defined(CONFIG_TH500_HWPM_IP_C_NVLINK) + case TH500_HWPM_IP_C_NVLINK: +#endif +#if defined(CONFIG_TH500_HWPM_IP_PCIE) + case TH500_HWPM_IP_PCIE: +#endif +#if defined(CONFIG_TH500_HWPM_IP_C2C) + case TH500_HWPM_IP_C2C: +#endif +#if defined(CONFIG_TH500_HWPM_IP_CL2) || \ + defined(CONFIG_TH500_HWPM_IP_SMMU) || \ + defined(CONFIG_TH500_HWPM_IP_C_NVLINK) || \ + defined(CONFIG_TH500_HWPM_IP_PCIE) || \ + defined(CONFIG_TH500_HWPM_IP_C2C) + ret = tegra_hwpm_set_fs_info_ip_ops(hwpm, ip_ops, + base_address, ip_idx, available); + if (ret != 0) { + tegra_hwpm_err(hwpm, + "IP %d base 0x%llx:Failed to %s fs/ops", + ip_idx, base_address, + available == true ? "set" : "reset"); + goto fail; + } + break; +#endif +#if defined(CONFIG_TH500_HWPM_IP_MSS_CHANNEL) + case TH500_HWPM_IP_MSS_CHANNEL: +#endif +#if defined(CONFIG_TH500_HWPM_IP_MCF_CORE) + case TH500_HWPM_IP_MCF_CORE: +#endif +#if defined(CONFIG_TH500_HWPM_IP_MCF_CLINK) + case TH500_HWPM_IP_MCF_CLINK: +#endif +#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: +#endif +#if defined(CONFIG_TH500_HWPM_IP_SOC_HUB) + case TH500_HWPM_IP_SOC_HUB: +#endif + /* + * MSS channel, MCF CORE, MCF CLINK, MCF C2C, MCF SOC, + * and SOC HUB share MC channels + */ + + /* Check base address in TH500_HWPM_IP_MSS_CHANNEL */ +#if defined(CONFIG_TH500_HWPM_IP_MSS_CHANNEL) + ip_idx = TH500_HWPM_IP_MSS_CHANNEL; + 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_CORE) + /* Check base address in TH500_HWPM_IP_MCF_CORE */ + ip_idx = TH500_HWPM_IP_MCF_CORE; + 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_CLINK) + /* Check base address in TH500_HWPM_IP_MCF_CLINK */ + ip_idx = TH500_HWPM_IP_MCF_CLINK; + 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_C2C) + /* Check base address in TH500_HWPM_IP_MCF_C2C */ + ip_idx = TH500_HWPM_IP_MCF_C2C; + 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_SOC) + /* Check base address in TH500_HWPM_IP_MCF_SOC */ + ip_idx = TH500_HWPM_IP_MCF_SOC; + 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_SOC_HUB) + /* Check base address in TH500_HWPM_IP_SOC_HUB */ + ip_idx = TH500_HWPM_IP_SOC_HUB; + 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 + break; + case TH500_HWPM_IP_PMA: + case TH500_HWPM_IP_RTR: + default: + tegra_hwpm_err(hwpm, "Invalid IP %d for ip_ops", ip_idx); + break; + } + +fail: + return ret; +} + +int th500_hwpm_validate_current_config(struct tegra_soc_hwpm *hwpm) +{ + u32 production_mode = 0U; + u32 security_mode = 0U; + u32 fa_mode = 0U; + u32 hwpm_global_disable = 0U; + u32 opt_hwpm_disable = 0U; + u32 idx = 0U; + int err; + struct tegra_soc_hwpm_chip *active_chip = hwpm->active_chip; + struct hwpm_ip *chip_ip = NULL; + + tegra_hwpm_fn(hwpm, " "); + + if (!tegra_hwpm_is_platform_silicon()) { + return 0; + } + + /* Read production mode fuse */ + err = tegra_hwpm_fuse_readl_prod_mode(hwpm, &production_mode); + if (err != 0) { + tegra_hwpm_err(hwpm, "prod mode fuse read failed"); + return err; + } + +#define TEGRA_FUSE_SECURITY_MODE 0xA0U + err = tegra_hwpm_fuse_readl( + hwpm, TEGRA_FUSE_SECURITY_MODE, &security_mode); + if (err != 0) { + tegra_hwpm_err(hwpm, "security mode fuse read failed"); + return err; + } + +#define TEGRA_FUSE_OPT_HWPM_DISABLE 0x2cU + err = tegra_hwpm_fuse_readl( + hwpm, TEGRA_FUSE_SECURITY_MODE, &opt_hwpm_disable); + if (err != 0) { + tegra_hwpm_err(hwpm, "opt hwpm disable fuse read failed"); + return err; + } + +#define TEGRA_FUSE_FA_MODE 0x48U + err = tegra_hwpm_fuse_readl(hwpm, TEGRA_FUSE_FA_MODE, &fa_mode); + if (err != 0) { + tegra_hwpm_err(hwpm, "fa mode fuse read failed"); + return err; + } + +#define TEGRA_HWPM_GLOBAL_DISABLE_OFFSET 0x3CU +#define TEGRA_HWPM_GLOBAL_DISABLE_DISABLED 0x1U + err = tegra_hwpm_read_sticky_bits(hwpm, addr_map_pmc_misc_base_r(), + TEGRA_HWPM_GLOBAL_DISABLE_OFFSET, &hwpm_global_disable); + if (err != 0) { + tegra_hwpm_err(hwpm, "hwpm global disable read failed"); + return err; + } + + tegra_hwpm_dbg(hwpm, hwpm_info, + "PROD_MODE fuse = 0x%x " + "SECURITY_MODE fuse = 0x%x " + "HWPM disable fuse = 0x%x" + "FA mode fuse = 0x%x" + "HWPM_GLOBAL_DISABLE sticky bit = 0x%x", + production_mode, security_mode, opt_hwpm_disable, + fa_mode, hwpm_global_disable); + + /* Do not enable override if FA mode fuse is set */ + if (fa_mode != 0U) { + tegra_hwpm_dbg(hwpm, hwpm_info, + "fa mode fuse enabled, no override required"); + return 0; + } + + /* Override enable depends on security mode and global hwpm disable */ + if ((security_mode == 0U) && + (hwpm_global_disable == TEGRA_HWPM_GLOBAL_DISABLE_DISABLED)) { + tegra_hwpm_dbg(hwpm, hwpm_info, + "security fuses are disabled, no override required"); + return 0; + } + + for (idx = 0U; idx < active_chip->get_ip_max_idx(hwpm); idx++) { + chip_ip = active_chip->chip_ips[idx]; + + if ((hwpm_global_disable != + TEGRA_HWPM_GLOBAL_DISABLE_DISABLED) && + ((chip_ip->dependent_fuse_mask & + TEGRA_HWPM_FUSE_HWPM_GLOBAL_DISABLE_MASK) != 0U)) { + /* HWPM disable is true */ + /* IP depends on HWPM global disable */ + chip_ip->override_enable = true; + } else { + /* HWPM disable is false */ + if ((security_mode != 0U) && + ((chip_ip->dependent_fuse_mask & + TEGRA_HWPM_FUSE_SECURITY_MODE_MASK) != 0U)) { + /* Security mode fuse is set */ + /* IP depends on security mode fuse */ + chip_ip->override_enable = true; + } else { + /* + * This is a valid case since not all IPs + * depend on security fuse. + */ + tegra_hwpm_dbg(hwpm, hwpm_info, + "IP %d not overridden", idx); + } + } + } + + return 0; +} + +int th500_hwpm_force_enable_ips(struct tegra_soc_hwpm *hwpm) +{ + int ret = 0, err = 0; + + tegra_hwpm_fn(hwpm, " "); + +#if defined(CONFIG_TH500_HWPM_ALLOW_FORCE_ENABLE) + /* MSS CHANNEL */ +#if defined(CONFIG_TH500_HWPM_IP_MSS_CHANNEL) + ret = tegra_hwpm_set_fs_info_ip_ops(hwpm, NULL, + addr_map_mc0_base_r(), TH500_HWPM_IP_MSS_CHANNEL, true); + if (ret != 0) { + tegra_hwpm_err(hwpm, + "TH500_HWPM_IP_MSS_CHANNEL force enable failed"); + err = ret; + } +#endif +#if defined(CONFIG_TH500_HWPM_IP_C2C) + /* CTC Link */ + ret = tegra_hwpm_set_fs_info_ip_ops(hwpm, NULL, + addr_map_c2c0_base_r(), TH500_HWPM_IP_C2C, true); + if (ret != 0) { + tegra_hwpm_err(hwpm, + "TH500_HWPM_IP_C2C force enable failed"); + return ret; + } + + ret = tegra_hwpm_set_fs_info_ip_ops(hwpm, NULL, + addr_map_c2c5_base_r(), TH500_HWPM_IP_C2C, true); + if (ret != 0) { + tegra_hwpm_err(hwpm, + "TH500_HWPM_IP_C2C force enable failed"); + return ret; + } +#endif +#endif + return err; +} diff --git a/drivers/tegra/hwpm/os/linux/acpi.h b/drivers/tegra/hwpm/os/linux/acpi.h new file mode 100644 index 0000000..f579435 --- /dev/null +++ b/drivers/tegra/hwpm/os/linux/acpi.h @@ -0,0 +1,46 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ +/* + * Copyright (c) 2022-2023, NVIDIA CORPORATION & AFFILIATES. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + */ + +#ifndef TEGRA_HWPM_LINUX_HWPM_ACPI_H +#define TEGRA_HWPM_LINUX_HWPM_ACPI_H + +#if defined(CONFIG_ACPI) +#include + +/* + * The device data contains chip info as expected below: + * bit 23:20 - platform details + * bit 19:16 - minor number (not used in the driver) + * bit 15:08 - chip id + * bit 07:04 - chip id revision + */ +#if defined(CONFIG_TEGRA_TH500_HWPM) +static const unsigned long hwpm_th500_device_data = + (PLAT_SI << 20U) | (0x50U << 8U) | (0x0 << 4U); +#endif + +static const struct acpi_device_id tegra_hwpm_acpi_match[] = { +#if defined(CONFIG_TEGRA_TH500_HWPM) + { + .id = "NVDA2006", + .driver_data = hwpm_th500_device_data, + }, +#endif + { + }, +}; +MODULE_DEVICE_TABLE(acpi, tegra_hwpm_acpi_match); +#endif + +#endif /* TEGRA_HWPM_LINUX_HWPM_ACPI_H */ diff --git a/drivers/tegra/hwpm/os/linux/driver.c b/drivers/tegra/hwpm/os/linux/driver.c index 4f50cb3..c30a487 100644 --- a/drivers/tegra/hwpm/os/linux/driver.c +++ b/drivers/tegra/hwpm/os/linux/driver.c @@ -32,20 +32,18 @@ #include #include #include -#if defined(CONFIG_TEGRA_NEXT2_HWPM) -#include -#endif +#include static const struct of_device_id tegra_soc_hwpm_of_match[] = { { .compatible = "nvidia,t234-soc-hwpm", }, + { + .compatible = "nvidia,th500-soc-hwpm", + }, #ifdef CONFIG_TEGRA_NEXT1_HWPM #include #endif -#ifdef CONFIG_TEGRA_NEXT2_HWPM -#include -#endif #ifdef CONFIG_TEGRA_NEXT3_HWPM #include #endif @@ -262,7 +260,7 @@ static struct platform_driver tegra_soc_hwpm_pdrv = { .driver = { .name = TEGRA_SOC_HWPM_MODULE_NAME, .of_match_table = of_match_ptr(tegra_soc_hwpm_of_match), -#if defined(CONFIG_TEGRA_NEXT2_HWPM) && defined(CONFIG_ACPI) +#if defined(CONFIG_ACPI) .acpi_match_table = ACPI_PTR(tegra_hwpm_acpi_match), #endif }, diff --git a/drivers/tegra/hwpm/os/linux/log.h b/drivers/tegra/hwpm/os/linux/log.h index 7173980..2012b67 100644 --- a/drivers/tegra/hwpm/os/linux/log.h +++ b/drivers/tegra/hwpm/os/linux/log.h @@ -17,6 +17,8 @@ #ifndef TEGRA_HWPM_OS_LINUX_LOG_H #define TEGRA_HWPM_OS_LINUX_LOG_H +#include + struct tegra_soc_hwpm; void tegra_hwpm_err_impl(struct tegra_soc_hwpm *hwpm, diff --git a/drivers/tegra/hwpm/os/linux/soc_utils.c b/drivers/tegra/hwpm/os/linux/soc_utils.c index 69cfd89..d4d66eb 100644 --- a/drivers/tegra/hwpm/os/linux/soc_utils.c +++ b/drivers/tegra/hwpm/os/linux/soc_utils.c @@ -31,9 +31,6 @@ #if defined(CONFIG_TEGRA_NEXT1_HWPM) #include #endif -#if defined(CONFIG_TEGRA_NEXT2_HWPM) -#include -#endif #if defined(CONFIG_TEGRA_NEXT3_HWPM) #include #endif @@ -51,11 +48,19 @@ static const struct hwpm_soc_chip_info t234_soc_chip_info = { .platform = PLAT_SI, }; +#if !defined(CONFIG_ACPI) +const struct hwpm_soc_chip_info th500_chip_info = { + .chip_id = 0x50, + .chip_id_rev = 0x0, + .platform = PLAT_SI, +}; +#endif + /* This function should be invoked only once before retrieving soc chip info */ int tegra_hwpm_init_chip_info(struct tegra_hwpm_os_linux *hwpm_linux) { - struct device *dev = hwpm_linux->dev; #if defined(CONFIG_ACPI) + struct device *dev = hwpm_linux->dev; const struct acpi_device_id *id; #endif @@ -82,13 +87,17 @@ int tegra_hwpm_init_chip_info(struct tegra_hwpm_os_linux *hwpm_linux) goto complete; } -#if defined(CONFIG_TEGRA_NEXT1_HWPM) - if (tegra_hwpm_next1_get_chip_compatible(&chip_info) == 0) { +#if !defined(CONFIG_ACPI) + if (of_machine_is_compatible("nvidia,tegra500")) { + chip_info.chip_id = th500_chip_info.chip_id; + chip_info.chip_id_rev = th500_chip_info.chip_id_rev; + chip_info.platform = th500_chip_info.platform; + goto complete; } -#endif -#if defined(CONFIG_TEGRA_NEXT2_HWPM) - if (tegra_hwpm_next2_get_chip_compatible(&chip_info) == 0) { +#endif /* CONFIG_ACPI */ +#if defined(CONFIG_TEGRA_NEXT1_HWPM) + if (tegra_hwpm_next1_get_chip_compatible(&chip_info) == 0) { goto complete; } #endif