diff --git a/common/allowlist.c b/common/allowlist.c index 30a4055..4fecdd8 100644 --- a/common/allowlist.c +++ b/common/allowlist.c @@ -11,25 +11,12 @@ * more details. */ -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include - #include #include #include #include #include - int tegra_hwpm_get_allowlist_size(struct tegra_soc_hwpm *hwpm) { int ret = 0; diff --git a/common/init.c b/common/init.c index 7b8c56a..fa09c65 100644 --- a/common/init.c +++ b/common/init.c @@ -11,23 +11,10 @@ * more details. */ -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - #include #include #include +#include #include #include @@ -123,19 +110,10 @@ int tegra_hwpm_init_sw_components(struct tegra_soc_hwpm *hwpm) void tegra_hwpm_release_sw_components(struct tegra_soc_hwpm *hwpm) { - struct hwpm_ip_register_list *node = ip_register_list_head; - struct hwpm_ip_register_list *tmp_node = NULL; - tegra_hwpm_fn(hwpm, " "); hwpm->active_chip->release_sw_setup(hwpm); - while (node != NULL) { - tmp_node = node; - node = tmp_node->next; - tegra_hwpm_kfree(hwpm, tmp_node); - } - tegra_hwpm_kfree(hwpm, hwpm->active_chip->chip_ips); tegra_hwpm_kfree(hwpm, hwpm); tegra_soc_hwpm_pdev = NULL; diff --git a/common/ip.c b/common/ip.c index 6770ac8..a5493b5 100644 --- a/common/ip.c +++ b/common/ip.c @@ -11,67 +11,13 @@ * more details. */ -#include -#include - #include #include +#include #include #include #include -int tegra_hwpm_get_floorsweep_info(struct tegra_soc_hwpm *hwpm, - struct tegra_soc_hwpm_ip_floorsweep_info *fs_info) -{ - int ret = 0; - u32 i = 0U; - - tegra_hwpm_fn(hwpm, " "); - - for (i = 0U; i < fs_info->num_queries; i++) { - ret = hwpm->active_chip->get_fs_info( - hwpm, (u32)fs_info->ip_fsinfo[i].ip, - &fs_info->ip_fsinfo[i].ip_inst_mask, - &fs_info->ip_fsinfo[i].status); - if (ret < 0) { - /* Print error for debug purpose. */ - tegra_hwpm_err(hwpm, "Failed to get fs_info"); - } - - tegra_hwpm_dbg(hwpm, hwpm_info | hwpm_dbg_floorsweep_info, - "Query %d: ip %d: ip_status: %d inst_mask 0x%llx", - i, fs_info->ip_fsinfo[i].ip, - fs_info->ip_fsinfo[i].status, - fs_info->ip_fsinfo[i].ip_inst_mask); - } - return ret; -} - -int tegra_hwpm_get_resource_info(struct tegra_soc_hwpm *hwpm, - struct tegra_soc_hwpm_resource_info *rsrc_info) -{ - int ret = 0; - u32 i = 0U; - - tegra_hwpm_fn(hwpm, " "); - - for (i = 0U; i < rsrc_info->num_queries; i++) { - ret = hwpm->active_chip->get_resource_info( - hwpm, (u32)rsrc_info->resource_info[i].resource, - &rsrc_info->resource_info[i].status); - if (ret < 0) { - /* Print error for debug purpose. */ - tegra_hwpm_err(hwpm, "Failed to get rsrc_info"); - } - - tegra_hwpm_dbg(hwpm, hwpm_info | hwpm_dbg_resource_info, - "Query %d: resource %d: status: %d", - i, rsrc_info->resource_info[i].resource, - rsrc_info->resource_info[i].status); - } - return ret; -} - int tegra_hwpm_ip_handle_power_mgmt(struct tegra_soc_hwpm *hwpm, struct hwpm_ip_inst *ip_inst, bool disable) { @@ -143,7 +89,7 @@ static int tegra_hwpm_update_ip_inst_fs_mask(struct tegra_soc_hwpm *hwpm, } static int tegra_hwpm_update_ip_ops_info(struct tegra_soc_hwpm *hwpm, - struct tegra_soc_hwpm_ip_ops *hwpm_ip_ops, + struct tegra_hwpm_ip_ops *ip_ops, u32 ip_idx, u32 a_type, u32 inst_idx, bool available) { struct tegra_soc_hwpm_chip *active_chip = hwpm->active_chip; @@ -152,18 +98,18 @@ static int tegra_hwpm_update_ip_ops_info(struct tegra_soc_hwpm *hwpm, &chip_ip->inst_aperture_info[a_type]; struct hwpm_ip_inst *ip_inst = inst_a_info->inst_arr[inst_idx]; /* Update IP ops info for the instance */ - struct tegra_hwpm_ip_ops *ip_ops = &ip_inst->ip_ops; + struct tegra_hwpm_ip_ops *ops = &ip_inst->ip_ops; tegra_hwpm_fn(hwpm, " "); if (available) { - ip_ops->ip_dev = hwpm_ip_ops->ip_dev; - ip_ops->hwpm_ip_pm = hwpm_ip_ops->hwpm_ip_pm; - ip_ops->hwpm_ip_reg_op = hwpm_ip_ops->hwpm_ip_reg_op; + ops->ip_dev = ip_ops->ip_dev; + ops->hwpm_ip_pm = ip_ops->hwpm_ip_pm; + ops->hwpm_ip_reg_op = ip_ops->hwpm_ip_reg_op; } else { - ip_ops->ip_dev = NULL; - ip_ops->hwpm_ip_pm = NULL; - ip_ops->hwpm_ip_reg_op = NULL; + ops->ip_dev = NULL; + ops->hwpm_ip_pm = NULL; + ops->hwpm_ip_reg_op = NULL; } return 0; @@ -173,7 +119,7 @@ static int tegra_hwpm_update_ip_ops_info(struct tegra_soc_hwpm *hwpm, * Find IP hw instance mask and update IP floorsweep info and IP ops. */ int tegra_hwpm_set_fs_info_ip_ops(struct tegra_soc_hwpm *hwpm, - struct tegra_soc_hwpm_ip_ops *hwpm_ip_ops, + struct tegra_hwpm_ip_ops *ip_ops, u64 base_address, u32 ip_idx, bool available) { int ret = 0; @@ -215,9 +161,9 @@ int tegra_hwpm_set_fs_info_ip_ops(struct tegra_soc_hwpm *hwpm, tegra_hwpm_err(hwpm, "Invalid element type %d", element_type); } - if (hwpm_ip_ops != NULL) { + if (ip_ops != NULL) { /* Update IP ops */ - ret = tegra_hwpm_update_ip_ops_info(hwpm, hwpm_ip_ops, + ret = tegra_hwpm_update_ip_ops_info(hwpm, ip_ops, ip_idx, a_type, inst_idx, available); if (ret != 0) { tegra_hwpm_err(hwpm, @@ -240,27 +186,6 @@ fail: return ret; } -static int tegra_hwpm_complete_ip_register(struct tegra_soc_hwpm *hwpm) -{ - int ret = 0; - struct hwpm_ip_register_list *node = ip_register_list_head; - - tegra_hwpm_fn(hwpm, " "); - - while (node != NULL) { - ret = hwpm->active_chip->extract_ip_ops( - hwpm, &node->ip_ops, true); - if (ret != 0) { - tegra_hwpm_err(hwpm, - "Resource enum %d extract IP ops failed", - node->ip_ops.resource_enum); - return ret; - } - node = node->next; - } - return ret; -} - /* * There are 3 ways to get info about available IPs * 1. IP register to HWPM driver diff --git a/common/resource.c b/common/resource.c index c555af3..8074e27 100644 --- a/common/resource.c +++ b/common/resource.c @@ -11,9 +11,6 @@ * more details. */ -#include -#include - #include #include #include diff --git a/hal/t234/t234_interface.c b/hal/t234/t234_interface.c index 424f8d4..f8f2c67 100644 --- a/hal/t234/t234_interface.c +++ b/hal/t234/t234_interface.c @@ -11,14 +11,10 @@ * more details. */ -#include -#include - +#include #include #include -#include #include -#include #include #include diff --git a/hal/t234/t234_internal.h b/hal/t234/t234_internal.h index 65eae22..47cdbaf 100644 --- a/hal/t234/t234_internal.h +++ b/hal/t234/t234_internal.h @@ -77,7 +77,8 @@ u32 t234_get_rtr_int_idx(struct tegra_soc_hwpm *hwpm); u32 t234_get_ip_max_idx(struct tegra_soc_hwpm *hwpm); int t234_hwpm_extract_ip_ops(struct tegra_soc_hwpm *hwpm, - struct tegra_soc_hwpm_ip_ops *hwpm_ip_ops, bool available); + u32 resource_enum, u64 base_address, + struct tegra_hwpm_ip_ops *ip_ops, bool available); int t234_hwpm_force_enable_ips(struct tegra_soc_hwpm *hwpm); int t234_hwpm_validate_current_config(struct tegra_soc_hwpm *hwpm); int t234_hwpm_get_fs_info(struct tegra_soc_hwpm *hwpm, diff --git a/hal/t234/t234_ip.c b/hal/t234/t234_ip.c index 02a7d9a..b09198a 100644 --- a/hal/t234/t234_ip.c +++ b/hal/t234/t234_ip.c @@ -28,7 +28,8 @@ * Extract given ip_ops and update corresponding IP structure. */ int t234_hwpm_extract_ip_ops(struct tegra_soc_hwpm *hwpm, - struct tegra_soc_hwpm_ip_ops *hwpm_ip_ops, bool available) + u32 resource_enum, u64 base_address, + struct tegra_hwpm_ip_ops *ip_ops, bool available) { int ret = 0; u32 ip_idx = 0U; @@ -36,16 +37,13 @@ int t234_hwpm_extract_ip_ops(struct tegra_soc_hwpm *hwpm, tegra_hwpm_fn(hwpm, " "); tegra_hwpm_dbg(hwpm, hwpm_dbg_ip_register, - "Extract IP ops for resource enum %d info", - hwpm_ip_ops->resource_enum); + "Extract IP ops for resource enum %d info", resource_enum); /* Convert tegra_soc_hwpm_resource to internal enum */ - if (!(t234_hwpm_is_resource_active(hwpm, - hwpm_ip_ops->resource_enum, &ip_idx))) { + if (!(t234_hwpm_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", - hwpm_ip_ops->resource_enum, - hwpm_ip_ops->ip_base_address); + resource_enum, base_address); goto fail; } @@ -89,13 +87,13 @@ int t234_hwpm_extract_ip_ops(struct tegra_soc_hwpm *hwpm, #if defined(CONFIG_T234_HWPM_IP_MSS_GPU_HUB) case T234_HWPM_IP_MSS_GPU_HUB: #endif - ret = tegra_hwpm_set_fs_info_ip_ops(hwpm, hwpm_ip_ops, - hwpm_ip_ops->ip_base_address, ip_idx, available); + ret = tegra_hwpm_set_fs_info_ip_ops(hwpm, ip_ops, + base_address, ip_idx, available); if (ret != 0) { tegra_hwpm_err(hwpm, "Failed to %s fs/ops for IP %d (base 0x%llx)", available == true ? "set" : "reset", - ip_idx, hwpm_ip_ops->ip_base_address); + ip_idx, base_address); goto fail; } break; @@ -113,8 +111,8 @@ int t234_hwpm_extract_ip_ops(struct tegra_soc_hwpm *hwpm, /* Check base address in T234_HWPM_IP_MSS_CHANNEL */ #if defined(CONFIG_T234_HWPM_IP_MSS_CHANNEL) ip_idx = T234_HWPM_IP_MSS_CHANNEL; - ret = tegra_hwpm_set_fs_info_ip_ops(hwpm, hwpm_ip_ops, - hwpm_ip_ops->ip_base_address, ip_idx, available); + 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 @@ -126,7 +124,7 @@ int t234_hwpm_extract_ip_ops(struct tegra_soc_hwpm *hwpm, if (ret != -ENODEV) { tegra_hwpm_err(hwpm, "IP %d base 0x%llx:Failed to %s fs/ops", - ip_idx, hwpm_ip_ops->ip_base_address, + ip_idx, base_address, available == true ? "set" : "reset"); goto fail; } @@ -136,8 +134,8 @@ int t234_hwpm_extract_ip_ops(struct tegra_soc_hwpm *hwpm, #if defined(CONFIG_T234_HWPM_IP_MSS_ISO_NISO_HUBS) /* Check base address in T234_HWPM_IP_MSS_ISO_NISO_HUBS */ ip_idx = T234_HWPM_IP_MSS_ISO_NISO_HUBS; - ret = tegra_hwpm_set_fs_info_ip_ops(hwpm, hwpm_ip_ops, - hwpm_ip_ops->ip_base_address, ip_idx, available); + 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 @@ -149,7 +147,7 @@ int t234_hwpm_extract_ip_ops(struct tegra_soc_hwpm *hwpm, if (ret != -ENODEV) { tegra_hwpm_err(hwpm, "IP %d base 0x%llx:Failed to %s fs/ops", - ip_idx, hwpm_ip_ops->ip_base_address, + ip_idx, base_address, available == true ? "set" : "reset"); goto fail; } @@ -159,8 +157,8 @@ int t234_hwpm_extract_ip_ops(struct tegra_soc_hwpm *hwpm, #if defined(CONFIG_T234_HWPM_IP_MSS_MCF) /* Check base address in T234_HWPM_IP_MSS_MCF */ ip_idx = T234_HWPM_IP_MSS_MCF; - ret = tegra_hwpm_set_fs_info_ip_ops(hwpm, hwpm_ip_ops, - hwpm_ip_ops->ip_base_address, ip_idx, available); + 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 @@ -172,7 +170,7 @@ int t234_hwpm_extract_ip_ops(struct tegra_soc_hwpm *hwpm, if (ret != -ENODEV) { tegra_hwpm_err(hwpm, "IP %d base 0x%llx:Failed to %s fs/ops", - ip_idx, hwpm_ip_ops->ip_base_address, + ip_idx, base_address, available == true ? "set" : "reset"); goto fail; } diff --git a/hal/t234/t234_regops_allowlist.h b/hal/t234/t234_regops_allowlist.h index 6a48bac..0c29321 100644 --- a/hal/t234/t234_regops_allowlist.h +++ b/hal/t234/t234_regops_allowlist.h @@ -19,7 +19,6 @@ #ifndef T234_HWPM_REGOPS_ALLOWLIST_H #define T234_HWPM_REGOPS_ALLOWLIST_H -#include #include extern struct allowlist t234_perfmon_alist[67]; diff --git a/hal/t234/t234_resource.c b/hal/t234/t234_resource.c index 72f1ad5..c9f4248 100644 --- a/hal/t234/t234_resource.c +++ b/hal/t234/t234_resource.c @@ -11,11 +11,6 @@ * more details. */ -#include -#include -#include -#include - #include #include #include diff --git a/include/tegra_hwpm.h b/include/tegra_hwpm.h index 26aad8a..f80eef5 100644 --- a/include/tegra_hwpm.h +++ b/include/tegra_hwpm.h @@ -30,12 +30,6 @@ #define TEGRA_SOC_HWPM_IP_INACTIVE ~(0U) -struct hwpm_ip_register_list { - struct tegra_soc_hwpm_ip_ops ip_ops; - struct hwpm_ip_register_list *next; -}; -extern struct hwpm_ip_register_list *ip_register_list_head; - /* * This structure is copy of struct tegra_soc_hwpm_ip_ops uapi structure. * This is not a hard requirement as tegra_hwpm_validate_ip_ops conversion @@ -352,7 +346,8 @@ struct tegra_soc_hwpm_chip { u32 (*get_ip_max_idx)(struct tegra_soc_hwpm *hwpm); int (*extract_ip_ops)(struct tegra_soc_hwpm *hwpm, - struct tegra_soc_hwpm_ip_ops *hwpm_ip_ops, bool available); + u32 resource_enum, u64 base_address, + struct tegra_hwpm_ip_ops *ip_ops, bool available); int (*force_enable_ips)(struct tegra_soc_hwpm *hwpm); int (*validate_current_config)(struct tegra_soc_hwpm *hwpm); int (*get_fs_info)(struct tegra_soc_hwpm *hwpm, diff --git a/include/tegra_hwpm_common.h b/include/tegra_hwpm_common.h index c80c660..a0eb289 100644 --- a/include/tegra_hwpm_common.h +++ b/include/tegra_hwpm_common.h @@ -14,18 +14,15 @@ #ifndef TEGRA_HWPM_COMMON_H #define TEGRA_HWPM_COMMON_H +#include + enum tegra_hwpm_funcs; enum hwpm_aperture_type; enum tegra_hwpm_element_type; struct tegra_hwpm_func_args; +struct tegra_hwpm_ip_ops; struct tegra_soc_hwpm; -struct tegra_soc_hwpm_exec_reg_ops; -struct tegra_soc_hwpm_ip_floorsweep_info; -struct tegra_soc_hwpm_resource_info; -struct tegra_soc_hwpm_alloc_pma_stream; -struct tegra_soc_hwpm_update_get_put; struct hwpm_ip; -struct tegra_soc_hwpm_ip_ops; struct hwpm_ip_inst; struct hwpm_ip_aperture; @@ -57,7 +54,7 @@ int tegra_hwpm_element_release(struct tegra_soc_hwpm *hwpm, struct hwpm_ip_aperture *perfmon); int tegra_hwpm_set_fs_info_ip_ops(struct tegra_soc_hwpm *hwpm, - struct tegra_soc_hwpm_ip_ops *hwpm_ip_ops, + struct tegra_hwpm_ip_ops *ip_ops, u64 base_address, u32 ip_idx, bool available); int tegra_hwpm_finalize_chip_info(struct tegra_soc_hwpm *hwpm); int tegra_hwpm_ip_handle_power_mgmt(struct tegra_soc_hwpm *hwpm, @@ -72,9 +69,4 @@ int tegra_hwpm_disable_triggers(struct tegra_soc_hwpm *hwpm); int tegra_hwpm_release_hw(struct tegra_soc_hwpm *hwpm); void tegra_hwpm_release_sw_setup(struct tegra_soc_hwpm *hwpm); -int tegra_hwpm_get_floorsweep_info(struct tegra_soc_hwpm *hwpm, - struct tegra_soc_hwpm_ip_floorsweep_info *fs_info); -int tegra_hwpm_get_resource_info(struct tegra_soc_hwpm *hwpm, - struct tegra_soc_hwpm_resource_info *rsrc_info); - #endif /* TEGRA_HWPM_COMMON_H */ diff --git a/include/tegra_hwpm_ip.h b/include/tegra_hwpm_ip.h new file mode 100644 index 0000000..1652abe --- /dev/null +++ b/include/tegra_hwpm_ip.h @@ -0,0 +1,29 @@ +/* + * Copyright (c) 2022, 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_IP_H +#define TEGRA_HWPM_IP_H + +#ifdef __KERNEL__ +#include +#else +int tegra_hwpm_complete_ip_register_impl(struct tegra_soc_hwpm *hwpm) +{ + return -EINVAL; +} +#endif + +#define tegra_hwpm_complete_ip_register(hwpm) \ + tegra_hwpm_complete_ip_register_impl(hwpm) + +#endif /* TEGRA_HWPM_IP_H */ diff --git a/include/tegra_hwpm_types.h b/include/tegra_hwpm_types.h new file mode 100644 index 0000000..f8373fb --- /dev/null +++ b/include/tegra_hwpm_types.h @@ -0,0 +1,21 @@ +/* + * Copyright (c) 2022, 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_TYPES_H +#define TEGRA_HWPM_TYPES_H + +#ifdef __KERNEL__ +#include +#endif + +#endif /* TEGRA_HWPM_TYPES_H */ diff --git a/os/linux/debugfs.c b/os/linux/debugfs.c index 45aa317..1e1f2d4 100644 --- a/os/linux/debugfs.c +++ b/os/linux/debugfs.c @@ -19,7 +19,6 @@ #include #include -/* FIXME: This is a placeholder for now. We can add debugfs nodes as needed. */ void tegra_hwpm_debugfs_init(struct tegra_soc_hwpm *hwpm) { if (!hwpm) { diff --git a/os/linux/driver.c b/os/linux/driver.c index 38f5ed1..252fd7c 100644 --- a/os/linux/driver.c +++ b/os/linux/driver.c @@ -24,9 +24,10 @@ #include #include -#include #include #include +#include +#include static const struct of_device_id tegra_soc_hwpm_of_match[] = { { @@ -242,6 +243,7 @@ static int tegra_hwpm_remove(struct platform_device *pdev) class_unregister(&hwpm->class); tegra_hwpm_debugfs_deinit(hwpm); + tegra_hwpm_release_ip_register_node(hwpm); tegra_hwpm_release_sw_components(hwpm); return 0; diff --git a/os/linux/driver.h b/os/linux/driver.h new file mode 100644 index 0000000..0145881 --- /dev/null +++ b/os/linux/driver.h @@ -0,0 +1,23 @@ +/* + * Copyright (c) 2022, 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_OS_LINUX_DRIVER_H +#define TEGRA_HWPM_OS_LINUX_DRIVER_H + +struct hwpm_ip_register_list { + struct tegra_soc_hwpm_ip_ops ip_ops; + struct hwpm_ip_register_list *next; +}; +extern struct hwpm_ip_register_list *ip_register_list_head; + +#endif /* TEGRA_HWPM_OS_LINUX_DRIVER_H */ diff --git a/os/linux/ioctl.c b/os/linux/ioctl.c index eedec54..821b0df 100644 --- a/os/linux/ioctl.c +++ b/os/linux/ioctl.c @@ -30,6 +30,7 @@ #include #include #include +#include #include #define LA_CLK_RATE 625000000UL diff --git a/os/linux/ip_utils.c b/os/linux/ip_utils.c index 5a21d26..60404d7 100644 --- a/os/linux/ip_utils.c +++ b/os/linux/ip_utils.c @@ -15,9 +15,12 @@ #include #include +#include #include #include #include +#include +#include struct platform_device *tegra_soc_hwpm_pdev; struct hwpm_ip_register_list *ip_register_list_head; @@ -82,6 +85,7 @@ static int tegra_hwpm_note_ip_register( void tegra_soc_hwpm_ip_register(struct tegra_soc_hwpm_ip_ops *hwpm_ip_ops) { struct tegra_soc_hwpm *hwpm = NULL; + struct tegra_hwpm_ip_ops ip_ops; int ret = 0; if (hwpm_ip_ops == NULL) { @@ -109,8 +113,13 @@ void tegra_soc_hwpm_ip_register(struct tegra_soc_hwpm_ip_ops *hwpm_ip_ops) tegra_hwpm_dbg(hwpm, hwpm_info | hwpm_dbg_ip_register, "Register IP 0x%llx", hwpm_ip_ops->ip_base_address); + ip_ops.ip_dev = hwpm_ip_ops->ip_dev; + ip_ops.hwpm_ip_pm = hwpm_ip_ops->hwpm_ip_pm; + ip_ops.hwpm_ip_reg_op = hwpm_ip_ops->hwpm_ip_reg_op; + ret = hwpm->active_chip->extract_ip_ops(hwpm, - hwpm_ip_ops, REGISTER_IP); + hwpm_ip_ops->resource_enum, + hwpm_ip_ops->ip_base_address, &ip_ops, REGISTER_IP); if (ret < 0) { tegra_hwpm_err(hwpm, "Failed to set IP ops for IP %d", hwpm_ip_ops->resource_enum); @@ -121,6 +130,7 @@ void tegra_soc_hwpm_ip_register(struct tegra_soc_hwpm_ip_ops *hwpm_ip_ops) void tegra_soc_hwpm_ip_unregister(struct tegra_soc_hwpm_ip_ops *hwpm_ip_ops) { struct tegra_soc_hwpm *hwpm = NULL; + struct tegra_hwpm_ip_ops ip_ops; int ret = 0; if (hwpm_ip_ops == NULL) { @@ -141,11 +151,109 @@ void tegra_soc_hwpm_ip_unregister(struct tegra_soc_hwpm_ip_ops *hwpm_ip_ops) tegra_hwpm_dbg(hwpm, hwpm_info | hwpm_dbg_ip_register, "Unregister IP 0x%llx", hwpm_ip_ops->ip_base_address); + ip_ops.ip_dev = hwpm_ip_ops->ip_dev; + ip_ops.hwpm_ip_pm = hwpm_ip_ops->hwpm_ip_pm; + ip_ops.hwpm_ip_reg_op = hwpm_ip_ops->hwpm_ip_reg_op; + ret = hwpm->active_chip->extract_ip_ops(hwpm, - hwpm_ip_ops, UNREGISTER_IP); + hwpm_ip_ops->resource_enum, + hwpm_ip_ops->ip_base_address, &ip_ops, UNREGISTER_IP); if (ret < 0) { tegra_hwpm_err(hwpm, "Failed to reset IP ops for IP %d", hwpm_ip_ops->resource_enum); } } } + +int tegra_hwpm_complete_ip_register_impl(struct tegra_soc_hwpm *hwpm) +{ + int ret = 0; + struct hwpm_ip_register_list *node = ip_register_list_head; + struct tegra_hwpm_ip_ops ip_ops; + + tegra_hwpm_fn(hwpm, " "); + + while (node != NULL) { + ip_ops.ip_dev = node->ip_ops.ip_dev; + ip_ops.hwpm_ip_pm = node->ip_ops.hwpm_ip_pm; + ip_ops.hwpm_ip_reg_op = node->ip_ops.hwpm_ip_reg_op; + + ret = hwpm->active_chip->extract_ip_ops(hwpm, + node->ip_ops.resource_enum, + node->ip_ops.ip_base_address, &ip_ops, true); + if (ret != 0) { + tegra_hwpm_err(hwpm, + "Resource enum %d extract IP ops failed", + node->ip_ops.resource_enum); + return ret; + } + node = node->next; + } + return ret; +} + +int tegra_hwpm_get_floorsweep_info(struct tegra_soc_hwpm *hwpm, + struct tegra_soc_hwpm_ip_floorsweep_info *fs_info) +{ + int ret = 0; + u32 i = 0U; + + tegra_hwpm_fn(hwpm, " "); + + for (i = 0U; i < fs_info->num_queries; i++) { + ret = hwpm->active_chip->get_fs_info( + hwpm, (u32)fs_info->ip_fsinfo[i].ip, + &fs_info->ip_fsinfo[i].ip_inst_mask, + &fs_info->ip_fsinfo[i].status); + if (ret < 0) { + /* Print error for debug purpose. */ + tegra_hwpm_err(hwpm, "Failed to get fs_info"); + } + + tegra_hwpm_dbg(hwpm, hwpm_info | hwpm_dbg_floorsweep_info, + "Query %d: ip %d: ip_status: %d inst_mask 0x%llx", + i, fs_info->ip_fsinfo[i].ip, + fs_info->ip_fsinfo[i].status, + fs_info->ip_fsinfo[i].ip_inst_mask); + } + return ret; +} + +int tegra_hwpm_get_resource_info(struct tegra_soc_hwpm *hwpm, + struct tegra_soc_hwpm_resource_info *rsrc_info) +{ + int ret = 0; + u32 i = 0U; + + tegra_hwpm_fn(hwpm, " "); + + for (i = 0U; i < rsrc_info->num_queries; i++) { + ret = hwpm->active_chip->get_resource_info( + hwpm, (u32)rsrc_info->resource_info[i].resource, + &rsrc_info->resource_info[i].status); + if (ret < 0) { + /* Print error for debug purpose. */ + tegra_hwpm_err(hwpm, "Failed to get rsrc_info"); + } + + tegra_hwpm_dbg(hwpm, hwpm_info | hwpm_dbg_resource_info, + "Query %d: resource %d: status: %d", + i, rsrc_info->resource_info[i].resource, + rsrc_info->resource_info[i].status); + } + return ret; +} + +void tegra_hwpm_release_ip_register_node(struct tegra_soc_hwpm *hwpm) +{ + struct hwpm_ip_register_list *node = ip_register_list_head; + struct hwpm_ip_register_list *tmp_node = NULL; + + tegra_hwpm_fn(hwpm, " "); + + while (node != NULL) { + tmp_node = node; + node = tmp_node->next; + tegra_hwpm_kfree(hwpm, tmp_node); + } +} diff --git a/os/linux/ip_utils.h b/os/linux/ip_utils.h new file mode 100644 index 0000000..177f631 --- /dev/null +++ b/os/linux/ip_utils.h @@ -0,0 +1,28 @@ +/* + * Copyright (c) 2022, 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_OS_LINUX_IP_UTILS_H +#define TEGRA_HWPM_OS_LINUX_IP_UTILS_H + +struct tegra_soc_hwpm; +struct tegra_soc_hwpm_ip_floorsweep_info; +struct tegra_soc_hwpm_resource_info; + +int tegra_hwpm_complete_ip_register_impl(struct tegra_soc_hwpm *hwpm); +int tegra_hwpm_get_floorsweep_info(struct tegra_soc_hwpm *hwpm, + struct tegra_soc_hwpm_ip_floorsweep_info *fs_info); +int tegra_hwpm_get_resource_info(struct tegra_soc_hwpm *hwpm, + struct tegra_soc_hwpm_resource_info *rsrc_info); +void tegra_hwpm_release_ip_register_node(struct tegra_soc_hwpm *hwpm); + +#endif /* TEGRA_HWPM_OS_LINUX_IP_UTILS_H */